Home | History | Annotate | Download | only in x87

Lines Matching full:instr

336 void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
337 if (instr->IsCall()) {
340 if (!instr->IsLazyBailout() && !instr->IsGap()) {
343 FlushX87StackIfNecessary(instr);
347 void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) {
349 if (instr->IsCall() && instr->ClobbersDoubleRegisters(isolate())) {
350 bool double_result = instr->HasDoubleRegisterResult();
361 if (instr->IsGoto()) {
362 x87_stack_.LeavingBlock(current_block_, LGoto::cast(instr), this);
364 !instr->IsGap() && !instr->IsReturn()) {
365 if (instr->ClobbersDoubleRegisters(isolate())) {
366 if (instr->HasDoubleRegisterResult()) {
438 code->instr()->hydrogen_value()->id(),
439 code->instr()->Mnemonic());
685 void LCodeGen::X87Stack::FlushIfNecessary(LInstruction* instr, LCodeGen* cgen) {
686 if (stack_depth_ > 0 && instr->ClobbersDoubleRegisters(isolate())) {
687 bool double_inputs = instr->HasDoubleRegisterInput();
694 if (double_inputs && instr->IsDoubleInput(reg, cgen)) {
701 if (instr->IsReturn()) {
982 LInstruction* instr,
984 DCHECK(instr != NULL);
986 RecordSafepointWithLazyDeopt(instr, safepoint_mode);
999 LInstruction* instr) {
1000 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT);
1005 LInstruction* instr, SaveFPRegsMode save_doubles) {
1006 DCHECK(instr != NULL);
1007 DCHECK(instr->HasPointerMap());
1011 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
1035 LInstruction* instr,
1041 instr->pointer_map(), argc, Safepoint::kNoLazyDeopt);
1084 void LCodeGen::DeoptimizeIf(Condition cc, LInstruction* instr,
1087 LEnvironment* environment = instr->environment();
1148 Deoptimizer::Reason reason(instr->hydrogen_value()->position().raw(),
1149 instr->Mnemonic(), detail);
1172 void LCodeGen::DeoptimizeIf(Condition cc, LInstruction* instr,
1177 DeoptimizeIf(cc, instr, detail, bailout_type);
1252 LInstruction* instr, SafepointMode safepoint_mode) {
1254 RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt);
1258 instr->pointer_map(), 0, Safepoint::kLazyDeopt);
1354 void LCodeGen::DoInstructionGap(LInstructionGap* instr) {
1355 DoGap(instr);
1359 void LCodeGen::DoParameter(LParameter* instr) {
1364 void LCodeGen::DoCallStub(LCallStub* instr) {
1365 DCHECK(ToRegister(instr->context()).is(esi));
1366 DCHECK(ToRegister(instr->result()).is(eax));
1367 switch (instr->hydrogen()->major_key()) {
1370 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1375 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1380 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1389 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
1394 void LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) {
1395 Register dividend = ToRegister(instr->dividend());
1396 int32_t divisor = instr->divisor();
1397 DCHECK(dividend.is(ToRegister(instr->result())));
1405 HMod* hmod = instr->hydrogen();
1416 DeoptimizeIf(zero, instr, "minus zero");
1427 void LCodeGen::DoModByConstI(LModByConstI* instr) {
1428 Register dividend = ToRegister(instr->dividend());
1429 int32_t divisor = instr->divisor();
1430 DCHECK(ToRegister(instr->result()).is(eax));
1433 DeoptimizeIf(no_condition, instr, "division by zero");
1443 HMod* hmod = instr->hydrogen();
1448 DeoptimizeIf(less, instr, "minus zero");
1454 void LCodeGen::DoModI(LModI* instr) {
1455 HMod* hmod = instr->hydrogen();
1457 Register left_reg = ToRegister(instr->left());
1459 Register right_reg = ToRegister(instr->right());
1462 Register result_reg = ToRegister(instr->result());
1470 DeoptimizeIf(zero, instr, "division by zero");
1481 DeoptimizeIf(equal, instr, "minus zero");
1500 DeoptimizeIf(zero, instr, "minus zero");
1509 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
1510 Register dividend = ToRegister(instr->dividend());
1511 int32_t divisor = instr->divisor();
1512 Register result = ToRegister(instr->result());
1517 HDiv* hdiv = instr->hydrogen();
1520 DeoptimizeIf(zero, instr, "minus zero");
1525 DeoptimizeIf(zero, instr, "overflow");
1532 DeoptimizeIf(not_zero, instr, "lost precision");
1547 void LCodeGen::DoDivByConstI(LDivByConstI* instr) {
1548 Register dividend = ToRegister(instr->dividend());
1549 int32_t divisor = instr->divisor();
1550 DCHECK(ToRegister(instr->result()).is(edx));
1553 DeoptimizeIf(no_condition, instr, "division by zero");
1558 HDiv* hdiv = instr->hydrogen();
1561 DeoptimizeIf(zero, instr, "minus zero");
1571 DeoptimizeIf(not_equal, instr, "lost precision");
1577 void LCodeGen::DoDivI(LDivI* instr) {
1578 HBinaryOperation* hdiv = instr->hydrogen();
1579 Register dividend = ToRegister(instr->dividend());
1580 Register divisor = ToRegister(instr->divisor());
1581 Register remainder = ToRegister(instr->temp());
1584 DCHECK(ToRegister(instr->result()).is(eax));
1591 DeoptimizeIf(zero, instr, "division by zero");
1600 DeoptimizeIf(sign, instr, "minus zero");
1610 DeoptimizeIf(zero, instr, "overflow");
1621 DeoptimizeIf(not_zero, instr, "lost precision");
1626 void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
1627 Register dividend = ToRegister(instr->dividend());
1628 int32_t divisor = instr->divisor();
1629 DCHECK(dividend.is(ToRegister(instr->result())));
1642 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1643 DeoptimizeIf(zero, instr, "minus zero");
1648 if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
1649 DeoptimizeIf(overflow, instr, "overflow");
1655 if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
1670 void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
1671 Register dividend = ToRegister(instr->dividend());
1672 int32_t divisor = instr->divisor();
1673 DCHECK(ToRegister(instr->result()).is(edx));
1676 DeoptimizeIf(no_condition, instr, "division by zero");
1681 HMathFloorOfDiv* hdiv = instr->hydrogen();
1684 DeoptimizeIf(zero, instr, "minus zero");
1698 Register temp = ToRegister(instr->temp3());
1716 void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) {
1717 HBinaryOperation* hdiv = instr->hydrogen();
1718 Register dividend = ToRegister(instr->dividend());
1719 Register divisor = ToRegister(instr->divisor());
1720 Register remainder = ToRegister(instr->temp());
1721 Register result = ToRegister(instr->result());
1731 DeoptimizeIf(zero, instr, "division by zero");
1740 DeoptimizeIf(sign, instr, "minus zero");
1750 DeoptimizeIf(zero, instr, "overflow");
1768 void LCodeGen::DoMulI(LMulI* instr) {
1769 Register left = ToRegister(instr->left());
1770 LOperand* right = instr->right();
1772 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1773 __ mov(ToRegister(instr->temp()), left);
1787 } else if (!instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1821 if (instr->hydrogen()->representation().IsSmi()) {
1827 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1828 DeoptimizeIf(overflow, instr, "overflow");
1831 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1838 DeoptimizeIf(no_condition, instr, "minus zero");
1840 __ cmp(ToRegister(instr->temp()), Immediate(0));
1841 DeoptimizeIf(less, instr, "minus zero");
1845 __ or_(ToRegister(instr->temp()), ToOperand(right));
1846 DeoptimizeIf(sign, instr, "minus zero");
1853 void LCodeGen::DoBitI(LBitI* instr) {
1854 LOperand* left = instr->left();
1855 LOperand* right = instr->right();
1856 DCHECK(left->Equals(instr->result()));
1862 instr->hydrogen()->representation());
1863 switch (instr->op()) {
1882 switch (instr->op()) {
1900 void LCodeGen::DoShiftI(LShiftI* instr) {
1901 LOperand* left = instr->left();
1902 LOperand* right = instr->right();
1903 DCHECK(left->Equals(instr->result()));
1908 switch (instr->op()) {
1917 if (instr->can_deopt()) {
1919 DeoptimizeIf(sign, instr, "negative value");
1932 switch (instr->op()) {
1934 if (shift_count == 0 && instr->can_deopt()) {
1936 DeoptimizeIf(sign, instr, "negative value");
1949 } else if (instr->can_deopt()) {
1951 DeoptimizeIf(sign, instr, "negative value");
1956 if (instr->hydrogen_value()->representation().IsSmi() &&
1957 instr->can_deopt()) {
1962 DeoptimizeIf(overflow, instr, "overflow");
1976 void LCodeGen::DoSubI(LSubI* instr) {
1977 LOperand* left = instr->left();
1978 LOperand* right = instr->right();
1979 DCHECK(left->Equals(instr->result()));
1983 ToImmediate(right, instr->hydrogen()->representation()));
1987 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1988 DeoptimizeIf(overflow, instr, "overflow");
1993 void LCodeGen::DoConstantI(LConstantI* instr) {
1994 __ Move(ToRegister(instr->result()), Immediate(instr->value()));
1998 void LCodeGen::DoConstantS(LConstantS* instr) {
1999 __ Move(ToRegister(instr->result()), Immediate(instr->value()));
2003 void LCodeGen::DoConstantD(LConstantD* instr) {
2004 double v = instr->value();
2008 DCHECK(instr->result()->IsDoubleRegister());
2012 X87Register reg = ToX87Register(instr->result());
2018 void LCodeGen::DoConstantE(LConstantE* instr) {
2019 __ lea(ToRegister(instr->result()), Operand::StaticVariable(instr->value()));
2023 void LCodeGen::DoConstantT(LConstantT* instr) {
2024 Register reg = ToRegister(instr->result());
2025 Handle<Object> object = instr->value(isolate());
2031 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
2032 Register result = ToRegister(instr->result());
2033 Register map = ToRegister(instr->value());
2038 void LCodeGen::DoDateField(LDateField* instr) {
2039 Register object = ToRegister(instr->date());
2040 Register result = ToRegister(instr->result());
2041 Register scratch = ToRegister(instr->temp());
2042 Smi* index = instr->index();
2048 DeoptimizeIf(zero, instr, "Smi");
2050 DeoptimizeIf(not_equal, instr, "not a date object");
2093 void LCodeGen::DoSeqStringGetChar(LSeqStringGetChar* instr) {
2094 String::Encoding encoding = instr->hydrogen()->encoding();
2095 Register result = ToRegister(instr->result());
2096 Register string = ToRegister(instr->string());
2112 Operand operand = BuildSeqStringOperand(string, instr->index(), encoding);
2121 void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
2122 String::Encoding encoding = instr->hydrogen()->encoding();
2123 Register string = ToRegister(instr->string());
2126 Register value = ToRegister(instr->value());
2127 Register index = ToRegister(instr->index());
2131 instr->hydrogen()->encoding() == String::ONE_BYTE_ENCODING
2136 Operand operand = BuildSeqStringOperand(string, instr->index(), encoding);
2137 if (instr->value()->IsConstantOperand()) {
2138 int value = ToRepresentation(LConstantOperand::cast(instr->value()),
2149 Register value = ToRegister(instr->value());
2159 void LCodeGen::DoAddI(LAddI* instr) {
2160 LOperand* left = instr->left();
2161 LOperand* right = instr->right();
2163 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) {
2166 instr->hydrogen()->representation());
2167 __ lea(ToRegister(instr->result()), MemOperand(ToRegister(left), offset));
2170 __ lea(ToRegister(instr->result()), address);
2175 ToImmediate(right, instr->hydrogen()->representation()));
2179 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
2180 DeoptimizeIf(overflow, instr, "overflow");
2186 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
2187 LOperand* left = instr->left();
2188 LOperand* right = instr->right();
2189 DCHECK(left->Equals(instr->result()));
2190 HMathMinMax::Operation operation = instr->hydrogen()->operation();
2191 if (instr->hydrogen()->representation().IsSmiOrInteger32()) {
2198 Immediate immediate = ToImmediate(LConstantOperand::cast(instr->right()),
2199 instr->hydrogen()->representation());
2212 DCHECK(instr->hydrogen()->representation().IsDouble());
2218 X87PrepareBinaryOp(left_reg, right_reg, ToX87Register(instr->result()));
2236 Register scratch_reg = ToRegister(instr->temp());
2268 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
2269 X87Register left = ToX87Register(instr->left());
2270 X87Register right = ToX87Register(instr->right());
2271 X87Register result = ToX87Register(instr->result());
2272 if (instr->op() != Token::MOD) {
2277 switch (instr->op()) {
2316 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
2317 DCHECK(ToRegister(instr->context()).is(esi));
2318 DCHECK(ToRegister(instr->left()).is(edx));
2319 DCHECK(ToRegister(instr->right()).is(eax));
2320 DCHECK(ToRegister(instr->result()).is(eax));
2323 CodeFactory::BinaryOpIC(isolate(), instr->op(), NO_OVERWRITE).code();
2324 CallCode(code, RelocInfo::CODE_TARGET, instr);
2329 void LCodeGen::EmitBranch(InstrType instr, Condition cc) {
2330 int left_block = instr->TrueDestination(chunk_);
2331 int right_block = instr->FalseDestination(chunk_);
2349 void LCodeGen::EmitFalseBranch(InstrType instr, Condition cc) {
2350 int false_block = instr->FalseDestination(chunk_);
2359 void LCodeGen::DoBranch(LBranch* instr) {
2360 Representation r = instr->hydrogen()->value()->representation();
2362 Register reg = ToRegister(instr->value());
2364 EmitBranch(instr, not_zero);
2366 X87Register reg = ToX87Register(instr->value());
2370 EmitBranch(instr, not_zero);
2373 Register reg = ToRegister(instr->value());
2374 HType type = instr->hydrogen()->value()->type();
2378 EmitBranch(instr, equal);
2382 EmitBranch(instr, not_equal);
2385 EmitBranch(instr, no_condition);
2391 EmitBranch(instr, not_equal);
2393 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
2399 __ j(equal, instr->FalseLabel(chunk_));
2404 __ j(equal, instr->TrueLabel(chunk_));
2407 __ j(equal, instr->FalseLabel(chunk_));
2412 __ j(equal, instr->FalseLabel(chunk_));
2418 __ j(equal, instr->FalseLabel(chunk_));
2419 __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
2423 DeoptimizeIf(zero, instr, "Smi");
2428 map = ToRegister(instr->temp());
2436 __ j(not_zero, instr->FalseLabel(chunk_));
2443 __ j(above_equal, instr->TrueLabel(chunk_));
2452 __ j(not_zero, instr->TrueLabel(chunk_));
2453 __ jmp(instr->FalseLabel(chunk_));
2460 __ j(equal, instr->TrueLabel(chunk_));
2472 __ j(zero, instr->FalseLabel(chunk_));
2473 __ jmp(instr->TrueLabel(chunk_));
2480 DeoptimizeIf(no_condition, instr, "unexpected object");
2494 void LCodeGen::DoClobberDoubles(LClobberDoubles* instr) {
2498 void LCodeGen::DoGoto(LGoto* instr) {
2499 EmitGoto(instr->block_id());
2535 void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) {
2536 LOperand* left = instr->left();
2537 LOperand* right = instr->right();
2539 instr->is_double() ||
2540 instr->hydrogen()->left()->CheckFlag(HInstruction::kUint32) ||
2541 instr->hydrogen()->right()->CheckFlag(HInstruction::kUint32);
2542 Condition cc = TokenToCondition(instr->op(), is_unsigned);
2548 int next_block = EvalComparison(instr->op(), left_val, right_val) ?
2549 instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_);
2552 if (instr->is_double()) {
2557 __ j(parity_even, instr->FalseLabel(chunk_));
2561 ToImmediate(right, instr->hydrogen()->representation()));
2564 ToImmediate(left, instr->hydrogen()->representation()));
2571 EmitBranch(instr, cc);
2576 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
2577 Register left = ToRegister(instr->left());
2579 if (instr->right()->IsConstantOperand()) {
2580 Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right()));
2583 Operand right = ToOperand(instr->right());
2586 EmitBranch(instr, equal);
2590 void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
2591 if (instr->hydrogen()->representation().IsTagged()) {
2592 Register input_reg = ToRegister(instr->object());
2594 EmitBranch(instr, equal);
2599 X87Register src = ToX87Register(instr->object());
2607 EmitFalseBranch(instr, no_condition);
2617 EmitBranch(instr, equal);
2621 void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
2622 Representation rep = instr->hydrogen()->value()->representation();
2626 X87Register input = ToX87Register(instr->value());
2629 EmitBranch(instr, equal);
2631 Register value = ToRegister(instr->value());
2633 __ CheckMap(value, map, instr->FalseLabel(chunk()), DO_SMI_CHECK);
2636 EmitFalseBranch(instr, no_overflow);
2639 EmitBranch(instr, equal);
2667 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
2668 Register reg = ToRegister(instr->value());
2669 Register temp = ToRegister(instr->temp());
2672 reg, temp, instr->FalseLabel(chunk_), instr->TrueLabel(chunk_));
2674 EmitBranch(instr, true_cond);
2692 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
2693 Register reg = ToRegister(instr->value());
2694 Register temp = ToRegister(instr->temp());
2697 instr->hydrogen()->value()->type().IsHeapObject()
2701 reg, temp, instr->FalseLabel(chunk_), check_needed);
2703 EmitBranch(instr, true_cond);
2707 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
2708 Operand input = ToOperand(instr->value());
2711 EmitBranch(instr, zero);
2715 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
2716 Register input = ToRegister(instr->value());
2717 Register temp = ToRegister(instr->temp());
2719 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
2721 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2726 EmitBranch(instr, not_zero);
2750 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
2751 Token::Value op = instr->op();
2754 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2759 EmitBranch(instr, condition);
2763 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
2764 InstanceType from = instr->from();
2765 InstanceType to = instr->to();
2772 static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
2773 InstanceType from = instr->from();
2774 InstanceType to = instr->to();
2783 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
2784 Register input = ToRegister(instr->value());
2785 Register temp = ToRegister(instr->temp());
2787 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
2788 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2791 __ CmpObjectType(input, TestType(instr->hydrogen()), temp);
2792 EmitBranch(instr, BranchCondition(instr->hydrogen()));
2796 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
2797 Register input = ToRegister(instr->value());
2798 Register result = ToRegister(instr->result());
2808 LHasCachedArrayIndexAndBranch* instr) {
2809 Register input = ToRegister(instr->value());
2813 EmitBranch(instr, equal);
2882 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2883 Register input = ToRegister(instr->value());
2884 Register temp = ToRegister(instr->temp());
2885 Register temp2 = ToRegister(instr->temp2());
2887 Handle<String> class_name = instr->hydrogen()->class_name();
2889 EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
2892 EmitBranch(instr, equal);
2896 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
2897 Register reg = ToRegister(instr->value());
2898 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map());
2899 EmitBranch(instr, equal);
2903 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
2905 DCHECK(ToRegister(instr->context()).is(esi));
2907 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2912 __ mov(ToRegister(instr->result()), factory()->false_value());
2915 __ mov(ToRegister(instr->result()), factory()->true_value());
2920 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
2924 LInstanceOfKnownGlobal* instr,
2926 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
2930 virtual LInstruction* instr() OVERRIDE { return instr_; }
2938 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr, x87_stack_);
2941 Register object = ToRegister(instr->value());
2942 Register temp = ToRegister(instr->temp());
2951 Register map = ToRegister(instr->temp());
2975 __ mov(ToRegister(instr->result()), factory()->false_value());
2984 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
3001 Register temp = ToRegister(instr->temp());
3003 __ LoadHeapObject(InstanceofStub::right(), instr->function());
3010 instr,
3014 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment();
3022 void LCodeGen::DoCmpT(LCmpT* instr) {
3023 Token::Value op = instr->op();
3026 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3032 __ mov(ToRegister(instr->result()), factory()->false_value());
3035 __ mov(ToRegister(instr->result()), factory()->true_value());
3040 void LCodeGen::EmitReturn(LReturn* instr, bool dynamic_frame_alignment) {
3043 if (instr->has_constant_parameter_count()) {
3044 int parameter_count = ToInteger32(instr->constant_parameter_count());
3053 Register reg = ToRegister(instr->parameter_count());
3065 // emit code to restore stack based on instr->parameter_count()
3077 void LCodeGen::DoReturn(LReturn* instr) {
3103 EmitReturn(instr, true);
3107 EmitReturn(instr, false);
3114 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
3115 Register result = ToRegister(instr->result());
3116 __ mov(result, Operand::ForCell(instr->hydrogen()->cell().handle()));
3117 if (instr->hydrogen()->RequiresHoleCheck()) {
3119 DeoptimizeIf(equal, instr, "hole");
3125 void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
3127 Register vector = ToRegister(instr->temp_vector());
3129 __ mov(vector, instr->hydrogen()->feedback_vector());
3133 Immediate(Smi::FromInt(instr->hydrogen()->slot())));
3137 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
3138 DCHECK(ToRegister(instr->context()).is(esi));
3139 DCHECK(ToRegister(instr->global_object())
3141 DCHECK(ToRegister(instr->result()).is(eax));
3143 __ mov(LoadDescriptor::NameRegister(), instr->name());
3145 EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
3147 ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
3149 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3153 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
3154 Register value = ToRegister(instr->value());
3155 Handle<PropertyCell> cell_handle = instr->hydrogen()->cell().handle();
3161 if (instr->hydrogen()->RequiresHoleCheck()) {
3163 DeoptimizeIf(equal, instr, "hole");
3172 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
3173 Register context = ToRegister(instr->context());
3174 Register result = ToRegister(instr->result());
3175 __ mov(result, ContextOperand(context, instr->slot_index()));
3177 if (instr->hydrogen()->RequiresHoleCheck()) {
3179 if (instr->hydrogen()->DeoptimizesOnHole()) {
3180 DeoptimizeIf(equal, instr, "hole");
3191 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
3192 Register context = ToRegister(instr->context());
3193 Register value = ToRegister(instr->value());
3197 Operand target = ContextOperand(context, instr->slot_index());
3198 if (instr->hydrogen()->RequiresHoleCheck()) {
3200 if (instr->hydrogen()->DeoptimizesOnHole()) {
3201 DeoptimizeIf(equal, instr, "hole");
3208 if (instr->hydrogen()->NeedsWriteBarrier()) {
3210 instr->hydrogen()->value()->type().IsHeapObject()
3212 Register temp = ToRegister(instr->temp());
3213 int offset = Context::SlotOffset(instr->slot_index());
3222 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
3223 HObjectAccess access = instr->hydrogen()->access();
3227 Register result = ToRegister(instr->result());
3228 MemOperand operand = instr->object()->IsConstantOperand()
3230 LConstantOperand::cast(instr->object())))
3231 : MemOperand(ToRegister(instr->object()), offset);
3236 Register object = ToRegister(instr->object());
3237 if (instr->hydrogen()->representation().IsDouble()) {
3238 X87Mov(ToX87Register(instr->result()), FieldOperand(object, offset));
3242 Register result = ToRegister(instr->result());
3269 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
3270 DCHECK(ToRegister(instr->context()).is(esi));
3271 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister()));
3272 DCHECK(ToRegister(instr->result()).is(eax));
3274 __ mov(LoadDescriptor::NameRegister(), instr->name());
3276 EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
3279 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3283 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
3284 Register function = ToRegister(instr->function());
3285 Register temp = ToRegister(instr->temp());
3286 Register result = ToRegister(instr->result());
3294 DeoptimizeIf(equal, instr, "hole");
3309 void LCodeGen::DoLoadRoot(LLoadRoot* instr) {
3310 Register result = ToRegister(instr->result());
3311 __ LoadRoot(result, instr->index());
3315 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
3316 Register arguments = ToRegister(instr->arguments());
3317 Register result = ToRegister(instr->result());
3318 if (instr->length()->IsConstantOperand() &&
3319 instr->index()->IsConstantOperand()) {
3320 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3321 int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
3325 Register length = ToRegister(instr->length());
3326 Operand index = ToOperand(instr->index());
3335 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
3336 ElementsKind elements_kind = instr->elements_kind();
3337 LOperand* key = instr->key();
3339 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(),
3344 instr->elements(),
3346 instr->hydrogen()->key()->representation(),
3348 instr->base_offset()));
3351 X87Mov(ToX87Register(instr->result()), operand, kX87FloatOperand);
3354 X87Mov(ToX87Register(instr->result()), operand);
3356 Register result(ToRegister(instr->result()));
3383 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
3385 DeoptimizeIf(negative, instr, "negative value");
3407 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
3408 if (instr->hydrogen()->RequiresHoleCheck()) {
3410 instr->elements(), instr->key(),
3411 instr->hydrogen()->key()->representation(),
3413 instr->base_offset() + sizeof(kHoleNanLower32));
3415 DeoptimizeIf(equal, instr, "hole");
3419 instr->elements(),
3420 instr->key(),
3421 instr->hydrogen()->key()->representation(),
3423 instr->base_offset());
3424 X87Mov(ToX87Register(instr->result()), double_load_operand);
3428 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3429 Register result = ToRegister(instr->result());
3433 BuildFastArrayOperand(instr->elements(), instr->key(),
3434 instr->hydrogen()->key()->representation(),
3435 FAST_ELEMENTS, instr->base_offset()));
3438 if (instr->hydrogen()->RequiresHoleCheck()) {
3439 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
3441 DeoptimizeIf(not_equal, instr, "not a Smi");
3444 DeoptimizeIf(equal, instr, "hole");
3450 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
3451 if (instr->is_typed_elements()) {
3452 DoLoadKeyedExternalArray(instr);
3453 } else if (instr->hydrogen()->representation().IsDouble()) {
3454 DoLoadKeyedFixedDoubleArray(instr);
3456 DoLoadKeyedFixedArray(instr);
3492 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
3493 DCHECK(ToRegister(instr->context()).is(esi));
3494 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister()));
3495 DCHECK(ToRegister(instr->key()).is(LoadDescriptor::NameRegister()));
3498 EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
3502 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3506 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
3507 Register result = ToRegister(instr->result());
3509 if (instr->hydrogen()->from_inlined()) {
3535 instr) {
3536 Operand elem = ToOperand(instr->elements());
3537 Register result = ToRegister(instr->result());
3557 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
3558 Register receiver = ToRegister(instr->receiver());
3559 Register function = ToRegister(instr->function());
3566 Register scratch = ToRegister(instr->temp());
3568 if (!instr->hydrogen()->known_function()) {
3591 DeoptimizeIf(equal, instr, "Smi");
3593 DeoptimizeIf(below, instr, "not a JavaScript object");
3606 void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
3607 Register receiver = ToRegister(instr->receiver());
3608 Register function = ToRegister(instr->function());
3609 Register length = ToRegister(instr->length());
3610 Register elements = ToRegister(instr->elements());
3613 DCHECK(ToRegister(instr->result()).is(eax));
3619 DeoptimizeIf(above, instr, "too many arguments");
3637 DCHECK(instr->HasPointerMap());
3638 LPointerMap* pointers = instr->pointer_map();
3646 void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
3651 void LCodeGen::DoPushArgument(LPushArgument* instr) {
3652 LOperand* argument = instr->value();
3657 void LCodeGen::DoDrop(LDrop* instr) {
3658 __ Drop(instr->count());
3662 void LCodeGen::DoThisFunction(LThisFunction* instr) {
3663 Register result = ToRegister(instr->result());
3668 void LCodeGen::DoContext(LContext* instr) {
3669 Register result = ToRegister(instr->result());
3679 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
3680 DCHECK(ToRegister(instr->context()).is(esi));
3682 __ push(Immediate(instr->hydrogen()->pairs()));
3683 __ push(Immediate(Smi::FromInt(instr->hydrogen()->flags())));
3684 CallRuntime(Runtime::kDeclareGlobals, 3, instr);
3691 LInstruction* instr,
3718 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
3721 LPointerMap* pointers = instr->pointer_map();
3732 LTailCallThroughMegamorphicCache* instr) {
3733 Register receiver = ToRegister(instr->receiver());
3734 Register name = ToRegister(instr->name());
3747 isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(),
3757 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
3758 DCHECK(ToRegister(instr->result()).is(eax));
3760 LPointerMap* pointers = instr->pointer_map();
3763 if (instr->target()->IsConstantOperand()) {
3764 LConstantOperand* target = LConstantOperand::cast(instr->target());
3769 DCHECK(instr->target()->IsRegister());
3770 Register target = ToRegister(instr->target());
3779 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) {
3780 DCHECK(ToRegister(instr->function()).is(edi));
3781 DCHECK(ToRegister(instr->result()).is(eax));
3783 if (instr->hydrogen()->pass_argument_count()) {
3784 __ mov(eax, instr->arity());
3791 if (instr->hydrogen()->function()->IsConstant()) {
3792 HConstant* fun_const = HConstant::cast(instr->hydrogen()->function());
3804 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
3808 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3809 Register input_reg = ToRegister(instr->value());
3812 DeoptimizeIf(not_equal, instr, "not a heap number");
3835 instr, instr->context());
3853 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
3854 Register input_reg = ToRegister(instr->value());
3859 DeoptimizeIf(negative, instr, "overflow");
3864 void LCodeGen::DoMathAbs(LMathAbs* instr) {
3869 LMathAbs* instr,
3871 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
3875 virtual LInstruction* instr() OVERRIDE { return instr_; }
3880 DCHECK(instr->value()->Equals(instr->result()));
3881 Representation r = instr->hydrogen()->value()->representation();
3884 X87Register value = ToX87Register(instr->value());
3888 EmitIntegerMathAbs(instr);
3891 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr, x87_stack_);
3892 Register input_reg = ToRegister(instr->value());
3895 EmitIntegerMathAbs(instr);
3901 void LCodeGen::DoMathFloor(LMathFloor* instr) {
3902 Register output_reg = ToRegister(instr->result());
3903 X87Register input_reg = ToX87Register(instr->value());
3911 DeoptimizeIf(parity_even, instr, "NaN");
3914 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3920 DeoptimizeIf(not_zero, instr, "minus zero");
3934 DeoptimizeIf(equal, instr, "overflow");
3941 void LCodeGen::DoMathRound(LMathRound* instr) {
3942 X87Register input_reg = ToX87Register(instr->value());
3943 Register result = ToRegister(instr->result());
3968 DeoptimizeIf(equal, instr, "conversion overflow");
3981 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3985 DeoptimizeIf(not_zero, instr, "minus zero");
4002 DeoptimizeIf(equal, instr, "conversion overflow");
4011 void LCodeGen::DoMathFround(LMathFround* instr) {
4012 X87Register input_reg = ToX87Register(instr->value());
4021 void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
4022 X87Register input = ToX87Register(instr->value());
4023 X87Register result_reg = ToX87Register(instr->result());
4024 Register temp_result = ToRegister(instr->temp1());
4025 Register temp = ToRegister(instr->temp2());
4049 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4063 RecordSafepointWithRegisters(instr->pointer_map(), 1,
4084 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
4085 X87Register input_reg = ToX87Register(instr->value());
4086 DCHECK(ToX87Register(instr->result()).is(input_reg));
4113 void LCodeGen::DoPower(LPower* instr) {
4114 Representation exponent_type = instr->hydrogen()->right()->representation();
4115 X87Register result = ToX87Register(instr->result());
4117 X87Register base = ToX87Register(instr->left());
4121 Register exponent = ToRegister(instr->right());
4128 Register exponent = ToRegister(instr->right());
4134 DeoptimizeIf(not_equal, instr, "not a heap number");
4146 Register exponent = ToRegister(instr->right());
4153 X87Register exponent_double = ToX87Register(instr->right());
4184 void LCodeGen::DoMathLog(LMathLog* instr) {
4185 DCHECK(instr->value()->Equals(instr->result()));
4186 X87Register input_reg = ToX87Register(instr->value());
4222 void LCodeGen::DoMathClz32(LMathClz32* instr) {
4223 Register input = ToRegister(instr->value());
4224 Register result = ToRegister(instr->result());
4236 void LCodeGen::DoMathExp(LMathExp* instr) {
4237 X87Register input = ToX87Register(instr->value());
4238 X87Register result_reg = ToX87Register(instr->result());
4239 Register temp_result = ToRegister(instr->temp1());
4240 Register temp = ToRegister(instr->temp2());
4263 RecordSafepointWithRegisters(instr->pointer_map(), 0,
4278 RecordSafepointWithRegisters(instr->pointer_map(), 1,
4299 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
4300 DCHECK(ToRegister(instr->context()).is(esi));
4301 DCHECK(ToRegister(instr->function()).is(edi));
4302 DCHECK(instr->HasPointerMap());
4304 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
4306 LPointerMap* pointers = instr->pointer_map();
4309 ParameterCount count(instr->arity());
4313 instr->hydrogen()->formal_parameter_count(),
4314 instr->arity(),
4315 instr,
4321 void LCodeGen::DoCallFunction(LCallFunction* instr) {
4322 DCHECK(ToRegister(instr->context()).is(esi));
4323 DCHECK(ToRegister(instr->function()).is(edi));
4324 DCHECK(ToRegister(instr->result()).is(eax));
4326 int arity = instr->arity();
4327 CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
4328 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
4332 void LCodeGen::DoCallNew(LCallNew* instr) {
4333 DCHECK(ToRegister(instr->context()).is(esi));
4334 DCHECK(ToRegister(instr->constructor()).is(edi));
4335 DCHECK(ToRegister(instr->result()).is(eax));
4340 __ Move(eax, Immediate(instr->arity()));
4341 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
4345 void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
4346 DCHECK(ToRegister(instr->context()).is(esi));
4347 DCHECK(ToRegister(instr->constructor()).is(edi));
4348 DCHECK(ToRegister(instr->result()).is(eax));
4350 __ Move(eax, Immediate(instr->arity()));
4352 ElementsKind kind = instr->hydrogen()->elements_kind();
4358 if (instr->arity() == 0) {
4360 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
4361 } else if (instr->arity() == 1) {
4375 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
4381 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
4385 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
4390 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
4391 DCHECK(ToRegister(instr->context()).is(esi));
4392 CallRuntime(instr->function(), instr->arity(), instr, instr->save_doubles());
4396 void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) {
4397 Register function = ToRegister(instr->function());
4398 Register code_object = ToRegister(instr->code_object());
4404 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
4405 Register result = ToRegister(instr->result());
4406 Register base = ToRegister(instr->base_object());
4407 if (instr->offset()->IsConstantOperand()) {
4408 LConstantOperand* offset = LConstantOperand::cast(instr->offset());
4411 Register offset = ToRegister(instr->offset());
4417 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
4418 Representation representation = instr->hydrogen()->field_representation();
4420 HObjectAccess access = instr->hydrogen()->access();
4424 DCHECK(!instr->hydrogen()->NeedsWriteBarrier());
4425 MemOperand operand = instr->object()->IsConstantOperand()
4427 ToExternalReference(LConstantOperand::cast(instr->object())))
4428 : MemOperand(ToRegister(instr->object()), offset);
4429 if (instr->value()->IsConstantOperand()) {
4430 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4433 Register value = ToRegister(instr->value());
4439 Register object = ToRegister(instr->object());
4442 !instr->value()->IsConstantOperand() ||
4443 IsSmi(LConstantOperand::cast(instr->value())));
4446 DCHECK(!instr->hydrogen()->has_transition());
4447 DCHECK(!instr->hydrogen()->NeedsWriteBarrier());
4448 X87Register value = ToX87Register(instr->value());
4453 if (instr->hydrogen()->has_transition()) {
4454 Handle<Map> transition = instr->hydrogen()->transition_map();
4457 if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
4458 Register temp = ToRegister(instr->temp());
4459 Register temp_map = ToRegister(instr->temp_map());
4470 write_register = ToRegister(instr->temp());
4475 if (instr->value()->IsConstantOperand()) {
4476 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4482 DCHECK(!instr->hydrogen()->NeedsWriteBarrier());
4486 DCHECK(!instr->hydrogen()->NeedsWriteBarrier());
4490 Register value = ToRegister(instr->value());
4494 if (instr->hydrogen()->NeedsWriteBarrier()) {
4495 Register value = ToRegister(instr->value());
4496 Register temp = access.IsInobject() ? ToRegister(instr->temp()) : object;
4500 instr->hydrogen()->SmiCheckForWriteBarrier(),
4501 instr->hydrogen()->PointersToHereCheckForValue());
4506 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
4507 DCHECK(ToRegister(instr->context()).is(esi));
4508 instr->object()).is(StoreDescriptor::ReceiverRegister()));
4509 DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister()));
4511 __ mov(StoreDescriptor::NameRegister(), instr->name());
4512 Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode());
4513 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4517 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
4518 Condition cc = instr->hydrogen()->allow_equality() ? above : above_equal;
4519 if (instr->index()->IsConstantOperand()) {
4520 __ cmp(ToOperand(instr->length()),
4521 ToImmediate(LConstantOperand::cast(instr->index()),
4522 instr->hydrogen()->length()->representation()));
4524 } else if (instr->length()->IsConstantOperand()) {
4525 __ cmp(ToOperand(instr->index()),
4526 ToImmediate(LConstantOperand::cast(instr->length()),
4527 instr->hydrogen()->index()->representation()));
4529 __ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
4531 if (FLAG_debug_code && instr->hydrogen()->skip_check()) {
4537 DeoptimizeIf(cc, instr, "out of bounds");
4542 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4543 ElementsKind elements_kind = instr->elements_kind();
4544 LOperand* key = instr->key();
4546 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(),
4551 instr->elements(),
4553 instr->hydrogen()->key()->representation(),
4555 instr->base_offset()));
4558 X87Mov(operand, ToX87Register(instr->value()), kX87FloatOperand);
4561 X87Mov(operand, ToX87Register(instr->value()));
4563 Register value = ToRegister(instr->value());
4604 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
4608 instr->elements(),
4609 instr->key(),
4610 instr->hydrogen()->key()->representation(),
4612 instr->base_offset());
4615 if (instr->hydrogen()->IsConstantHoleStore()) {
4625 instr->elements(),
4626 instr->key(),
4627 instr->hydrogen()->key()->representation(),
4629 instr->base_offset() + kPointerSize);
4633 X87Register value = ToX87Register(instr->value());
4636 if (instr->NeedsCanonicalization()) {
4661 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4662 Register elements = ToRegister(instr->elements());
4663 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
4666 instr->elements(),
4667 instr->key(),
4668 instr->hydrogen()->key()->representation(),
4670 instr->base_offset());
4671 if (instr->value()->IsRegister()) {
4672 __ mov(operand, ToRegister(instr->value()));
4674 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4685 if (instr->hydrogen()->NeedsWriteBarrier()) {
4686 DCHECK(instr->value()->IsRegister());
4687 Register value = ToRegister(instr->value());
4688 DCHECK(!instr->key()->IsConstantOperand());
4690 instr->hydrogen()->value()->type().IsHeapObject()
4696 instr->hydrogen()->PointersToHereCheckForValue());
4701 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
4703 if (instr->is_typed_elements()) {
4704 DoStoreKeyedExternalArray(instr);
4705 } else if (instr->hydrogen()->value()->representation().IsDouble()) {
4706 DoStoreKeyedFixedDoubleArray(instr);
4708 DoStoreKeyedFixedArray(instr);
4713 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
4714 DCHECK(ToRegister(instr->context()).is(esi));
4715 DCHECK(ToRegister(instr->object()).is(StoreDescriptor::ReceiverRegister()));
4716 DCHECK(ToRegister(instr->key()).is(StoreDescriptor::NameRegister()));
4717 DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister()));
4720 CodeFactory::KeyedStoreIC(isolate(), instr->strict_mode()).code();
4721 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4725 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
4726 Register object = ToRegister(instr->object());
4727 Register temp = ToRegister(instr->temp());
4730 DeoptimizeIf(equal, instr, "memento found");
4735 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
4736 Register object_reg = ToRegister(instr->object());
4738 Handle<Map> from_map = instr->original_map();
4739 Handle<Map> to_map = instr->transitioned_map();
4740 ElementsKind from_kind = instr->from_kind();
4741 ElementsKind to_kind = instr->to_kind();
4751 Register new_map_reg = ToRegister(instr->new_map_temp());
4755 DCHECK_NE(instr->temp(), NULL);
4757 ToRegister(instr->temp()), kDontSaveFPRegs);
4759 DCHECK(ToRegister(instr->context()).is(esi));
4766 RecordSafepointWithLazyDeopt(instr,
4773 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
4777 LStringCharCodeAt* instr,
4779 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
4783 virtual LInstruction* instr() OVERRIDE { return instr_; }
4789 new(zone()) DeferredStringCharCodeAt(this, instr, x87_stack_);
4793 ToRegister(instr->string()),
4794 ToRegister(instr->index()),
4795 ToRegister(instr->result()),
4801 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
4802 Register string = ToRegister(instr->string());
4803 Register result = ToRegister(instr->result());
4815 if (instr->index()->IsConstantOperand()) {
4816 Immediate immediate = ToImmediate(LConstantOperand::cast(instr->index()),
4820 Register index = ToRegister(instr->index());
4825 instr, instr->context());
4832 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
4836 LStringCharFromCode* instr,
4838 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
4842 virtual LInstruction* instr() OVERRIDE { return instr_; }
4848 new(zone()) DeferredStringCharFromCode(this, instr, x87_stack_);
4850 DCHECK(instr->hydrogen()->value()->representation().IsInteger32());
4851 Register char_code = ToRegister(instr->char_code());
4852 Register result = ToRegister(instr->result());
4867 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
4868 Register char_code = ToRegister(instr->char_code());
4869 Register result = ToRegister(instr->result());
4879 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context());
4884 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4885 DCHECK(ToRegister(instr->context()).is(esi));
4886 DCHECK(ToRegister(instr->left()).is(edx));
4887 DCHECK(ToRegister(instr->right()).is(eax));
4889 instr->hydrogen()->flags(),
4890 instr->hydrogen()->pretenure_flag());
4891 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
4895 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4896 LOperand* input = instr->value();
4897 LOperand* output = instr->result();
4911 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4912 LOperand* input = instr->value();
4913 LOperand* output = instr->result();
4921 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4925 LNumberTagI* instr,
4927 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
4932 virtual LInstruction* instr() OVERRIDE { return instr_; }
4937 LOperand* input = instr->value();
4938 DCHECK(input->IsRegister() && input->Equals(instr->result()));
4942 new(zone()) DeferredNumberTagI(this, instr, x87_stack_);
4949 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4953 LNumberTagU* instr,
4955 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
4960 virtual LInstruction* instr() OVERRIDE { return instr_; }
4965 LOperand* input = instr->value();
4966 DCHECK(input->IsRegister() && input->Equals(instr->result()));
4970 instr, x87_stack_);
4978 void LCodeGen::DoDeferredNumberTagIU(LInstruction* instr,
5029 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
5038 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
5042 LNumberTagD* instr,
5044 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
5048 virtual LInstruction* instr() OVERRIDE { return instr_; }
5053 Register reg = ToRegister(instr->result());
5056 X87Register src = ToX87Register(instr->value());
5062 new(zone()) DeferredNumberTagD(this, instr, x87_stack_);
5064 Register tmp = ToRegister(instr->temp());
5074 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
5078 Register reg = ToRegister(instr->result());
5090 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
5095 void LCodeGen::DoSmiTag(LSmiTag* instr) {
5096 HChange* hchange = instr->hydrogen();
5097 Register input = ToRegister(instr->value());
5101 DeoptimizeIf(not_zero, instr, "overflow");
5106 DeoptimizeIf(overflow, instr, "overflow");
5111 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
5112 LOperand* input = instr->value();
5114 DCHECK(input->IsRegister() && input->Equals(instr->result()));
5115 if (instr->needs_check()) {
5117 DeoptimizeIf(not_zero, instr, "not a Smi");
5125 void LCodeGen::EmitNumberUntagDNoSSE2(LNumberUntagD* instr, Register input_reg,
5129 instr->hydrogen()->can_convert_undefined_to_nan();
5130 bool deoptimize_on_minus_zero = instr->hydrogen()->deoptimize_on_minus_zero();
5143 DeoptimizeIf(not_equal, instr, "not a heap number");
5150 DeoptimizeIf(not_equal, instr, "not a heap number/undefined");
5175 DeoptimizeIf(not_zero, instr, "minus zero");
5195 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) {
5196 Register input_reg = ToRegister(instr->value());
5202 if (instr->truncating()) {
5228 DeoptimizeIf(not_equal, instr, "not a heap number/undefined/true/false");
5235 DeoptimizeIf(not_equal, instr, "not a heap number");
5240 if (instr->hydrogen()->GetMinusZeroMode() == FAIL_ON_MINUS_ZERO) {
5251 DeoptimizeIf(no_condition, instr, "lost precision");
5256 DeoptimizeIf(no_condition, instr, "NaN");
5271 DeoptimizeIf(not_zero, instr, "minus zero");
5277 DeoptimizeIf(not_equal, instr, "lost precision");
5278 DeoptimizeIf(parity_even, instr, "NaN");
5284 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
5288 LTaggedToI* instr,
5290 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
5294 virtual LInstruction* instr() OVERRIDE { return instr_; }
5299 LOperand* input = instr->value();
5302 DCHECK(input_reg.is(ToRegister(instr->result())));
5304 if (instr->hydrogen()->value()->representation().IsSmi()) {
5308 new(zone()) DeferredTaggedToI(this, instr, x87_stack_);
5321 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
5322 LOperand* input = instr->value();
5324 LOperand* temp = instr->temp();
5326 LOperand* result = instr->result();
5332 HValue* value = instr->hydrogen()->value();
5336 EmitNumberUntagDNoSSE2(instr, input_reg, temp_reg, ToX87Register(result),
5341 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
5342 LOperand* input = instr->value();
5344 LOperand* result = instr->result();
5348 if (instr->truncating()) {
5357 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(),
5361 DeoptimizeIf(no_condition, instr, "lost precision");
5363 DeoptimizeIf(no_condition, instr, "NaN");
5365 DeoptimizeIf(no_condition, instr, "minus zero");
5371 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
5372 LOperand* input = instr->value();
5374 LOperand* result = instr->result();
5382 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(),
5386 DeoptimizeIf(no_condition, instr, "lost precision");
5388 DeoptimizeIf(no_condition, instr, "NaN");
5390 DeoptimizeIf(no_condition, instr, "minus zero");
5393 DeoptimizeIf(overflow, instr, "overflow");
5397 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
5398 LOperand* input = instr->value();
5400 DeoptimizeIf(not_zero, instr, "not a Smi");
5404 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
5405 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
5406 LOperand* input = instr->value();
5408 DeoptimizeIf(zero, instr, "Smi");
5413 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
5414 Register input = ToRegister(instr->value());
5415 Register temp = ToRegister(instr->temp());
5419 if (instr->hydrogen()->is_interval_check()) {
5422 instr->hydrogen()->GetCheckInterval(&first, &last);
5429 DeoptimizeIf(not_equal, instr, "wrong instance type");
5431 DeoptimizeIf(below, instr, "wrong instance type");
5436 DeoptimizeIf(above, instr, "wrong instance type");
5442 instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
5447 DeoptimizeIf(tag == 0 ? not_zero : zero, instr, "wrong instance type");
5452 DeoptimizeIf(not_equal, instr, "wrong instance type");
5458 instr) {
5459 Handle<HeapObject> object = instr->hydrogen()->object().handle();
5460 if (instr->hydrogen()->object_in_new_space()) {
5461 Register reg = ToRegister(instr->value());
5465 Operand operand = ToOperand(instr->value());
5468 DeoptimizeIf(not_equal, instr, "value mismatch");
5472 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
5479 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt);
5483 DeoptimizeIf(zero, instr, "instance migration failed");
5487 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
5491 LCheckMaps* instr,
5494 : LDeferredCode(codegen, x87_stack), instr_(instr), object_(object) {
5501 virtual LInstruction* instr() OVERRIDE { return instr_; }
5508 if (instr->hydrogen()->IsStabilityCheck()) {
5509 const UniqueSet<Map>* maps = instr->hydrogen()->maps();
5516 LOperand* input = instr->value();
5521 if (instr->hydrogen()->HasMigrationTarget()) {
5522 deferred = new(zone()) DeferredCheckMaps(this, instr, reg, x87_stack_);
5526 const UniqueSet<Map>* maps = instr->hydrogen()->maps();
5536 if (instr->hydrogen()->HasMigrationTarget()) {
5539 DeoptimizeIf(not_equal, instr, "wrong map");
5546 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
5547 X87Register value_reg = ToX87Register(instr->unclamped());
5548 Register result_reg = ToRegister(instr->result());
5554 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
5555 DCHECK(instr->unclamped()->Equals(instr->result()));
5556 Register value_reg = ToRegister(instr->result());
5561 void LCodeGen::DoClampTToUint8NoSSE2(LClampTToUint8NoSSE2* instr) {
5562 Register input_reg = ToRegister(instr->unclamped());
5563 Register result_reg = ToRegister(instr->result());
5564 Register scratch = ToRegister(instr->scratch());
5565 Register scratch2 = ToRegister(instr->scratch2());
5566 Register scratch3 = ToRegister(instr->scratch3());
5580 DeoptimizeIf(not_equal, instr, "not a heap number/undefined");
5683 void LCodeGen::DoDoubleBits(LDoubleBits* instr) {
5684 X87Register value_reg = ToX87Register(instr->value());
5685 Register result_reg = ToRegister(instr->result());
5689 if (instr->hydrogen()->bits() == HDoubleBits::HIGH) {
5698 void LCodeGen::DoConstructDouble(LConstructDouble* instr) {
5699 Register hi_reg = ToRegister(instr->hi());
5700 Register lo_reg = ToRegister(instr->lo());
5701 X87Register result_reg = ToX87Register(instr->result());
5713 void LCodeGen::DoAllocate(LAllocate* instr) {
5717 LAllocate* instr,
5719 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
5723 virtual LInstruction* instr() OVERRIDE { return instr_; }
5729 new(zone()) DeferredAllocate(this, instr, x87_stack_);
5731 Register result = ToRegister(instr->result());
5732 Register temp = ToRegister(instr->temp());
5736 if (instr->hydrogen()->MustAllocateDoubleAligned()) {
5739 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5740 DCHECK(!instr->hydrogen()->IsOldDataSpaceAllocation());
5741 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
5743 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5744 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
5748 if (instr->size()->IsConstantOperand()) {
5749 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5756 Register size = ToRegister(instr->size());
5762 if (instr->hydrogen()->MustPrefillWithFiller()) {
5763 if (instr->size()->IsConstantOperand()) {
5764 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5767 temp = ToRegister(instr->size());
5781 void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
5782 Register result = ToRegister(instr->result());
5790 if (instr->size()->IsRegister()) {
5791 Register size = ToRegister(instr->size());
5793 __ SmiTag(ToRegister(instr->size()));
5796 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5807 instr->hydrogen()->MustAllocateDoubleAligned());
5808 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5809 DCHECK(!instr->hydrogen()->IsOldDataSpaceAllocation());
5810 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
5812 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5813 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
5821 Runtime::kAllocateInTargetSpace, 2, instr, instr->context());
5826 void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
5827 DCHECK(ToRegister(instr->value()).is(eax));
5829 CallRuntime(Runtime::kToFastProperties, 1, instr);
5833 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
5834 DCHECK(ToRegister(instr->context()).is(esi));
5842 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
5843 __ LoadHeapObject(ecx, instr->hydrogen()->literals());
5851 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index())));
5852 __ push(Immediate(instr->hydrogen()->pattern()));
5853 __ push(Immediate(instr->hydrogen()->flags()));
5854 CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr);
5866 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr);
5885 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
5886 DCHECK(ToRegister(instr->context()).is(esi));
5889 bool pretenure = instr->hydrogen()->pretenure();
5890 if (!pretenure && instr->hydrogen()->has_no_literals()) {
5891 FastNewClosureStub stub(isolate(), instr->hydrogen()->strict_mode(),
5892 instr->hydrogen()->kind());
5893 __ mov(ebx, Immediate(instr->hydrogen()->shared_info()));
5894 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
5897 __ push(Immediate(instr->hydrogen()->shared_info()));
5900 CallRuntime(Runtime::kNewClosure, 3, instr);
5905 void LCodeGen::DoTypeof(LTypeof* instr) {
5906 DCHECK(ToRegister(instr->context()).is(esi));
5907 LOperand* input = instr->value();
5909 CallRuntime(Runtime::kTypeof, 1, instr);
5913 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
5914 Register input = ToRegister(instr->value());
5915 Condition final_branch_condition = EmitTypeofIs(instr, input);
5917 EmitBranch(instr, final_branch_condition);
5922 Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) {
5923 Label* true_label = instr->TrueLabel(chunk_);
5924 Label* false_label = instr->FalseLabel(chunk_);
5925 Handle<String> type_name = instr->type_literal();
5926 int left_block = instr->TrueDestination(chunk_);
5927 int right_block = instr->FalseDestination(chunk_);
5998 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
5999 Register temp = ToRegister(instr->temp());
6002 EmitBranch(instr, equal);
6038 void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
6040 DCHECK(instr->HasEnvironment());
6041 LEnvironment* env = instr->environment();
6047 void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
6048 Deoptimizer::BailoutType type = instr->hydrogen()->type();
6056 DeoptimizeIf(no_condition, instr, instr->hydrogen()->reason(), type);
6060 void LCodeGen::DoDummy(LDummy* instr) {
6065 void LCodeGen::DoDummyUse(LDummyUse* instr) {
6070 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
6075 instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
6076 DCHECK(instr->HasEnvironment());
6077 LEnvironment* env = instr->environment();
6082 void LCodeGen::DoStackCheck(LStackCheck* instr) {
6086 LStackCheck* instr,
6088 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
6092 virtual LInstruction* instr() OVERRIDE { return instr_; }
6097 DCHECK(instr->HasEnvironment());
6098 LEnvironment* env = instr->environment();
6101 if (instr->hydrogen()->is_function_entry()) {
6109 DCHECK(instr->context()->IsRegister());
6110 DCHECK(ToRegister(instr->context()).is(esi));
6113 instr);
6116 DCHECK(instr->hydrogen()->is_backwards_branch());
6119 new(zone()) DeferredStackCheck(this, instr, x87_stack_);
6125 __ bind(instr->done_label());
6126 deferred_stack_check->SetExit(instr->done_label());
6135 void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
6139 LEnvironment* environment = instr->environment();
6150 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
6151 DCHECK(ToRegister(instr->context()).is(esi));
6153 DeoptimizeIf(equal, instr, "undefined");
6156 DeoptimizeIf(equal, instr, "null");
6159 DeoptimizeIf(zero, instr, "Smi");
6163 DeoptimizeIf(below_equal, instr, "wrong instance type");
6174 CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr);
6178 DeoptimizeIf(not_equal, instr, "wrong map");
6183 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) {
6184 Register map = ToRegister(instr->map());
6185 Register result = ToRegister(instr->result());
6198 FieldOperand(result, FixedArray::SizeFor(instr->idx())));
6201 DeoptimizeIf(equal, instr, "no cache");
6205 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
6206 Register object = ToRegister(instr->value());
6207 __ cmp(ToRegister(instr->map()),
6209 DeoptimizeIf(not_equal, instr, "wrong map");
6213 void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
6222 instr->pointer_map(), 2, Safepoint::kNoLazyDeopt);
6227 void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
6231 LLoadFieldByIndex* instr,
6236 instr_(instr),
6243 virtual LInstruction* instr() OVERRIDE { return instr_; }
6250 Register object = ToRegister(instr->object());
6251 Register index = ToRegister(instr->index());
6255 this, instr, object, index, x87_stack_);
6284 void LCodeGen::DoStoreFrameContext(LStoreFrameContext* instr) {
6285 Register context = ToRegister(instr->context());
6290 void LCodeGen::DoAllocateBlockContext(LAllocateBlockContext* instr) {
6291 Handle<ScopeInfo> scope_info = instr->scope_info();
6293 __ push(ToRegister(instr->function()));
6294 CallRuntime(Runtime::kPushBlockContext, 2, instr);