Home | History | Annotate | Download | only in x64

Lines Matching refs:instr

266     LInstruction* instr = instructions_->at(current_instruction_);
269 if (instr->IsLabel()) {
270 emit_instructions = !LLabel::cast(instr)->HasReplacement();
274 if (FLAG_code_comments && instr->HasInterestingComment(this)) {
277 instr->hydrogen_value()->id(),
278 instr->Mnemonic());
281 RecordAndUpdatePosition(instr->position());
283 instr->CompileToNative(this);
343 code->instr()->hydrogen_value()->id(),
344 code->instr()->Mnemonic());
595 LInstruction* instr,
599 ASSERT(instr != NULL);
600 LPointerMap* pointers = instr->pointer_map();
603 RecordSafepointWithLazyDeopt(instr, safepoint_mode, argc);
616 LInstruction* instr) {
617 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT, 0);
623 LInstruction* instr) {
624 ASSERT(instr != NULL);
625 ASSERT(instr->HasPointerMap());
626 LPointerMap* pointers = instr->pointer_map();
630 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0);
636 LInstruction* instr) {
640 instr->pointer_map(), argc, Safepoint::kNoLazyDeopt);
826 LInstruction* instr, SafepointMode safepoint_mode, int argc) {
828 RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt);
832 instr->pointer_map(), argc, Safepoint::kLazyDeopt);
931 void LCodeGen::DoInstructionGap(LInstructionGap* instr) {
932 DoGap(instr);
936 void LCodeGen::DoParameter(LParameter* instr) {
941 void LCodeGen::DoCallStub(LCallStub* instr) {
942 ASSERT(ToRegister(instr->result()).is(rax));
943 switch (instr->hydrogen()->major_key()) {
946 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
951 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
956 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
961 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
966 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
970 TranscendentalCacheStub stub(instr->transcendental_type(),
972 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
981 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
987 void LCodeGen::DoModI(LModI* instr) {
988 HMod* hmod = instr->hydrogen();
994 Register left_reg = ToRegister(instr->left());
995 ASSERT(left_reg.is(ToRegister(instr->result())));
1008 DeoptimizeIf(zero, instr->environment());
1018 Register left_reg = ToRegister(instr->left());
1019 ASSERT(left_reg.is(ToRegister(instr->result())));
1020 Register right_reg = ToRegister(instr->right());
1027 DeoptimizeIf(not_equal, instr->environment());
1037 DeoptimizeIf(zero, instr->environment());
1047 Register left_reg = ToRegister(instr->left());
1049 Register right_reg = ToRegister(instr->right());
1052 Register result_reg = ToRegister(instr->result());
1060 DeoptimizeIf(zero, instr->environment());
1071 DeoptimizeIf(equal, instr->environment());
1093 DeoptimizeIf(zero, instr->environment());
1103 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
1104 ASSERT(instr->right()->IsConstantOperand());
1106 const Register dividend = ToRegister(instr->left());
1107 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right()));
1108 const Register result = ToRegister(instr->result());
1112 DeoptimizeIf(no_condition, instr->environment());
1126 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1127 DeoptimizeIf(zero, instr->environment());
1129 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1130 DeoptimizeIf(overflow, instr->environment());
1141 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1142 DeoptimizeIf(zero, instr->environment());
1152 Register reg1 = ToRegister(instr->temp());
1153 Register reg2 = ToRegister(instr->result());
1172 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1174 DeoptimizeIf(zero, instr->environment());
1186 void LCodeGen::DoDivI(LDivI* instr) {
1187 if (!instr->is_flooring() && instr->hydrogen()->HasPowerOf2Divisor()) {
1188 Register dividend = ToRegister(instr->left());
1190 HConstant::cast(instr->hydrogen()->right())->Integer32Value();
1199 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1201 DeoptimizeIf(zero, instr->environment());
1204 if (divisor == -1 && instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1206 DeoptimizeIf(zero, instr->environment());
1213 if (instr->hydrogen()->CheckFlag(
1231 DeoptimizeIf(not_zero, instr->environment());
1241 LOperand* right = instr->right();
1242 ASSERT(ToRegister(instr->result()).is(rax));
1243 ASSERT(ToRegister(instr->left()).is(rax));
1244 ASSERT(!ToRegister(instr->right()).is(rax));
1245 ASSERT(!ToRegister(instr->right()).is(rdx));
1251 if (instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) {
1253 DeoptimizeIf(zero, instr->environment());
1257 if (instr->hydrogen_value()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1262 DeoptimizeIf(sign, instr->environment());
1267 if (instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)) {
1272 DeoptimizeIf(zero, instr->environment());
1280 if (instr->is_flooring()) {
1288 } else if (!instr->hydrogen()->CheckFlag(
1292 DeoptimizeIf(not_zero, instr->environment());
1297 void LCodeGen::DoMulI(LMulI* instr) {
1298 Register left = ToRegister(instr->left());
1299 LOperand* right = instr->right();
1301 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1306 instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1349 if (instr->hydrogen_value()->representation().IsSmi()) {
1356 if (instr->hydrogen_value()->representation().IsSmi()) {
1365 DeoptimizeIf(overflow, instr->environment());
1368 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1375 DeoptimizeIf(no_condition, instr->environment());
1378 DeoptimizeIf(less, instr->environment());
1382 DeoptimizeIf(sign, instr->environment());
1386 DeoptimizeIf(sign, instr->environment());
1393 void LCodeGen::DoBitI(LBitI* instr) {
1394 LOperand* left = instr->left();
1395 LOperand* right = instr->right();
1396 ASSERT(left->Equals(instr->result()));
1401 switch (instr->op()) {
1420 switch (instr->op()) {
1436 switch (instr->op()) {
1454 void LCodeGen::DoShiftI(LShiftI* instr) {
1455 LOperand* left = instr->left();
1456 LOperand* right = instr->right();
1457 ASSERT(left->Equals(instr->result()));
1462 switch (instr->op()) {
1471 if (instr->can_deopt()) {
1473 DeoptimizeIf(negative, instr->environment());
1486 switch (instr->op()) {
1498 if (shift_count == 0 && instr->can_deopt()) {
1500 DeoptimizeIf(negative, instr->environment());
1507 if (instr->hydrogen_value()->representation().IsSmi()) {
1522 void LCodeGen::DoSubI(LSubI* instr) {
1523 LOperand* left = instr->left();
1524 LOperand* right = instr->right();
1525 instr->result()));
1531 if (instr->hydrogen_value()->representation().IsSmi()) {
1537 if (instr->hydrogen_value()->representation().IsSmi()) {
1544 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1545 DeoptimizeIf(overflow, instr->environment());
1550 void LCodeGen::DoConstantI(LConstantI* instr) {
1551 __ Set(ToRegister(instr->result()), instr->value());
1555 void LCodeGen::DoConstantS(LConstantS* instr) {
1556 __ Move(ToRegister(instr->result()), instr->value());
1560 void LCodeGen::DoConstantD(LConstantD* instr) {
1561 ASSERT(instr->result()->IsDoubleRegister());
1562 XMMRegister res = ToDoubleRegister(instr->result());
1563 double v = instr->value();
1570 Register tmp = ToRegister(instr->temp());
1577 void LCodeGen::DoConstantE(LConstantE* instr) {
1578 __ LoadAddress(ToRegister(instr->result()), instr->value());
1582 void LCodeGen::DoConstantT(LConstantT* instr) {
1583 Handle<Object> value = instr->value();
1585 __ LoadObject(ToRegister(instr->result()), value);
1589 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1590 Register result = ToRegister(instr->result());
1591 Register map = ToRegister(instr->value());
1596 void LCodeGen::DoElementsKind(LElementsKind* instr) {
1597 Register result = ToRegister(instr->result());
1598 Register input = ToRegister(instr->value());
1610 void LCodeGen::DoValueOf(LValueOf* instr) {
1611 Register input = ToRegister(instr->value());
1612 Register result = ToRegister(instr->result());
1616 if (!instr->hydrogen()->value()->IsHeapObject()) {
1630 void LCodeGen::DoDateField(LDateField* instr) {
1631 Register object = ToRegister(instr->date());
1632 Register result = ToRegister(instr->result());
1633 Smi* index = instr->index();
1639 DeoptimizeIf(cc, instr->environment());
1641 DeoptimizeIf(not_equal, instr->environment());
1668 void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
1669 Register string = ToRegister(instr->string());
1670 Register index = ToRegister(instr->index());
1671 Register value = ToRegister(instr->value());
1672 String::Encoding encoding = instr->encoding();
1698 void LCodeGen::DoThrow(LThrow* instr) {
1699 __ push(ToRegister(instr->value()));
1700 CallRuntime(Runtime::kThrow, 1, instr);
1709 void LCodeGen::DoAddI(LAddI* instr) {
1710 LOperand* left = instr->left();
1711 LOperand* right = instr->right();
1713 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) {
1716 __ leal(ToRegister(instr->result()),
1720 if (instr->hydrogen()->representation().IsSmi()) {
1721 __ lea(ToRegister(instr->result()), address);
1723 __ leal(ToRegister(instr->result()), address);
1731 if (instr->hydrogen_value()->representation().IsSmi()) {
1737 if (instr->hydrogen_value()->representation().IsSmi()) {
1743 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1744 DeoptimizeIf(overflow, instr->environment());
1750 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
1751 LOperand* left = instr->left();
1752 LOperand* right = instr->right();
1753 ASSERT(left->Equals(instr->result()));
1754 HMathMinMax::Operation operation = instr->hydrogen()->operation();
1755 if (instr->hydrogen()->representation().IsSmiOrInteger32()) {
1764 ASSERT(!instr->hydrogen_value()->representation().IsSmi());
1770 if (instr->hydrogen_value()->representation().IsSmi()) {
1779 if (instr->hydrogen_value()->representation().IsSmi()) {
1789 ASSERT(instr->hydrogen()->representation().IsDouble());
1825 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1826 XMMRegister left = ToDoubleRegister(instr->left());
1827 XMMRegister right = ToDoubleRegister(instr->right());
1828 XMMRegister result = ToDoubleRegister(instr->result());
1830 ASSERT(instr->op() == Token::MOD || left.is(result));
1831 switch (instr->op()) {
1863 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
1864 ASSERT(ToRegister(instr->left()).is(rdx));
1865 ASSERT(ToRegister(instr->right()).is(rax));
1866 ASSERT(ToRegister(instr->result()).is(rax));
1868 BinaryOpStub stub(instr->op(), NO_OVERWRITE);
1869 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1883 void LCodeGen::EmitBranch(InstrType instr, Condition cc) {
1884 int left_block = instr->TrueDestination(chunk_);
1885 int right_block = instr->FalseDestination(chunk_);
1905 void LCodeGen::EmitFalseBranch(InstrType instr, Condition cc) {
1906 int false_block = instr->FalseDestination(chunk_);
1911 void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
1916 void LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) {
1917 Representation r = instr->hydrogen()->value()->representation();
1919 EmitBranch(instr, no_condition);
1922 Register reg = ToRegister(instr->value());
1923 HType type = instr->hydrogen()->value()->type();
1925 EmitBranch(instr, no_condition);
1927 __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
1930 EmitBranch(instr, equal);
1935 void LCodeGen::DoBranch(LBranch* instr) {
1936 Representation r = instr->hydrogen()->value()->representation();
1939 Register reg = ToRegister(instr->value());
1941 EmitBranch(instr, not_zero);
1944 Register reg = ToRegister(instr->value());
1946 EmitBranch(instr, not_zero);
1949 XMMRegister reg = ToDoubleRegister(instr->value());
1952 EmitBranch(instr, not_equal);
1955 Register reg = ToRegister(instr->value());
1956 HType type = instr->hydrogen()->value()->type();
1960 EmitBranch(instr, equal);
1964 EmitBranch(instr, not_equal);
1967 EmitBranch(instr, no_condition);
1972 EmitBranch(instr, not_equal);
1976 EmitBranch(instr, not_equal);
1978 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
1985 __ j(equal, instr->FalseLabel(chunk_));
1990 __ j(equal, instr->TrueLabel(chunk_));
1993 __ j(equal, instr->FalseLabel(chunk_));
1998 __ j(equal, instr->FalseLabel(chunk_));
2004 __ j(equal, instr->FalseLabel(chunk_));
2005 __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
2009 DeoptimizeIf(zero, instr->environment());
2020 __ j(not_zero, instr->FalseLabel(chunk_));
2027 __ j(above_equal, instr->TrueLabel(chunk_));
2036 __ j(not_zero, instr->TrueLabel(chunk_));
2037 __ jmp(instr->FalseLabel(chunk_));
2044 __ j(equal, instr->TrueLabel(chunk_));
2054 __ j(zero, instr->FalseLabel(chunk_));
2055 __ jmp(instr->TrueLabel(chunk_));
2062 DeoptimizeIf(no_condition, instr->environment());
2076 void LCodeGen::DoGoto(LGoto* instr) {
2077 EmitGoto(instr->block_id());
2109 void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) {
2110 LOperand* left = instr->left();
2111 LOperand* right = instr->right();
2112 Condition cc = TokenToCondition(instr->op(), instr->is_double());
2118 int next_block = EvalComparison(instr->op(), left_val, right_val) ?
2119 instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_);
2122 if (instr->is_double()) {
2126 __ j(parity_even, instr->FalseLabel(chunk_));
2131 if (instr->hydrogen_value()->representation().IsSmi()) {
2138 if (instr->hydrogen_value()->representation().IsSmi()) {
2151 } else if (instr->hydrogen_value()->representation().IsSmi()) {
2165 EmitBranch(instr, cc);
2170 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
2171 Register left = ToRegister(instr->left());
2173 if (instr->right()->IsConstantOperand()) {
2174 Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right()));
2177 Register right = ToRegister(instr->right());
2180 EmitBranch(instr, equal);
2184 void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
2185 if (instr->hydrogen()->representation().IsTagged()) {
2186 Register input_reg = ToRegister(instr->object());
2188 EmitBranch(instr, equal);
2192 XMMRegister input_reg = ToDoubleRegister(instr->object());
2194 EmitFalseBranch(instr, parity_odd);
2202 EmitBranch(instr, equal);
2231 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
2232 Register reg = ToRegister(instr->value());
2235 reg, instr->FalseLabel(chunk_), instr->TrueLabel(chunk_));
2237 EmitBranch(instr, true_cond);
2255 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
2256 Register reg = ToRegister(instr->value());
2257 Register temp = ToRegister(instr->temp());
2260 instr->hydrogen()->value()->IsHeapObject()
2264 reg, temp, instr->FalseLabel(chunk_), check_needed);
2266 EmitBranch(instr, true_cond);
2270 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
2272 if (instr->value()->IsRegister()) {
2273 Register input = ToRegister(instr->value());
2276 Operand input = ToOperand(instr->value());
2279 EmitBranch(instr, is_smi);
2283 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
2284 Register input = ToRegister(instr->value());
2285 Register temp = ToRegister(instr->temp());
2287 if (!instr->hydrogen()->value()->IsHeapObject()) {
2288 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2293 EmitBranch(instr, not_zero);
2297 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
2298 Token::Value op = instr->op();
2301 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2306 EmitBranch(instr, condition);
2310 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
2311 InstanceType from = instr->from();
2312 InstanceType to = instr->to();
2319 static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
2320 InstanceType from = instr->from();
2321 InstanceType to = instr->to();
2330 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
2331 Register input = ToRegister(instr->value());
2333 if (!instr->hydrogen()->value()->IsHeapObject()) {
2334 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2337 __ CmpObjectType(input, TestType(instr->hydrogen()), kScratchRegister);
2338 EmitBranch(instr, BranchCondition(instr->hydrogen()));
2342 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
2343 Register input = ToRegister(instr->value());
2344 Register result = ToRegister(instr->result());
2355 LHasCachedArrayIndexAndBranch* instr) {
2356 Register input = ToRegister(instr->value());
2360 EmitBranch(instr, equal);
2432 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2433 Register input = ToRegister(instr->value());
2434 Register temp = ToRegister(instr->temp());
2435 Register temp2 = ToRegister(instr->temp2());
2436 Handle<String> class_name = instr->hydrogen()->class_name();
2438 EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
2441 EmitBranch(instr, equal);
2445 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
2446 Register reg = ToRegister(instr->value());
2448 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map());
2449 EmitBranch(instr, equal);
2453 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
2455 __ push(ToRegister(instr->left()));
2456 __ push(ToRegister(instr->right()));
2457 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
2461 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
2464 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex);
2469 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
2473 LInstanceOfKnownGlobal* instr)
2474 : LDeferredCode(codegen), instr_(instr) { }
2478 virtual LInstruction* instr() { return instr_; }
2487 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
2490 Register object = ToRegister(instr->value());
2500 Register map = ToRegister(instr->temp());
2508 __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex);
2527 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
2534 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
2542 __ push(ToRegister(instr->value()));
2543 __ PushHeapObject(instr->function());
2557 instr,
2561 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment();
2579 void LCodeGen::DoInstanceSize(LInstanceSize* instr) {
2580 Register object = ToRegister(instr->object());
2581 Register result = ToRegister(instr->result());
2587 void LCodeGen::DoCmpT(LCmpT* instr) {
2588 Token::Value op = instr->op();
2591 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2597 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
2600 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex);
2605 void LCodeGen::DoReturn(LReturn* instr) {
2630 if (instr->has_constant_parameter_count()) {
2631 __ Ret((ToInteger32(instr->constant_parameter_count()) + 1) * kPointerSize,
2634 Register reg = ToRegister(instr->parameter_count());
2649 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
2650 Register result = ToRegister(instr->result());
2651 __ LoadGlobalCell(result, instr->hydrogen()->cell());
2652 if (instr->hydrogen()->RequiresHoleCheck()) {
2654 DeoptimizeIf(equal, instr->environment());
2659 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
2660 ASSERT(ToRegister(instr->global_object()).is(rax));
2661 ASSERT(ToRegister(instr->result()).is(rax));
2663 __ Move(rcx, instr->name());
2664 RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET :
2667 CallCode(ic, mode, instr);
2671 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
2672 Register value = ToRegister(instr->value());
2673 Handle<Cell> cell_handle = instr->hydrogen()->cell();
2679 if (instr->hydrogen()->RequiresHoleCheck()) {
2681 Register cell = ToRegister(instr->temp());
2685 DeoptimizeIf(equal, instr->environment());
2697 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) {
2698 ASSERT(ToRegister(instr->global_object()).is(rdx));
2699 ASSERT(ToRegister(instr->value()).is(rax));
2701 __ Move(rcx, instr->name());
2702 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
2705 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr);
2709 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
2710 Register context = ToRegister(instr->context());
2711 Register result = ToRegister(instr->result());
2712 __ movq(result, ContextOperand(context, instr->slot_index()));
2713 if (instr->hydrogen()->RequiresHoleCheck()) {
2715 if (instr->hydrogen()->DeoptimizesOnHole()) {
2716 DeoptimizeIf(equal, instr->environment());
2727 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
2728 Register context = ToRegister(instr->context());
2729 Register value = ToRegister(instr->value());
2731 Operand target = ContextOperand(context, instr->slot_index());
2734 if (instr->hydrogen()->RequiresHoleCheck()) {
2736 if (instr->hydrogen()->DeoptimizesOnHole()) {
2737 DeoptimizeIf(equal, instr->environment());
2744 if (instr->hydrogen()->NeedsWriteBarrier()) {
2746 instr->hydrogen()->value()->IsHeapObject()
2748 int offset = Context::SlotOffset(instr->slot_index());
2749 Register scratch = ToRegister(instr->temp());
2763 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
2764 HObjectAccess access = instr->hydrogen()->access();
2768 Register result = ToRegister(instr->result());
2769 if (instr->object()->IsConstantOperand()) {
2771 __ load_rax(ToExternalReference(LConstantOperand::cast(instr->object())));
2773 Register object = ToRegister(instr->object());
2779 Register object = ToRegister(instr->object());
2781 instr->hydrogen()->representation().IsDouble()) {
2782 XMMRegister result = ToDoubleRegister(instr->result());
2787 Register result = ToRegister(instr->result());
2797 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
2798 ASSERT(ToRegister(instr->object()).is(rax));
2799 ASSERT(ToRegister(instr->result()).is(rax));
2801 __ Move(rcx, instr->name());
2803 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2807 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
2808 Register function = ToRegister(instr->function());
2809 Register result = ToRegister(instr->result());
2813 DeoptimizeIf(not_equal, instr->environment());
2827 DeoptimizeIf(equal, instr->environment());
2849 LLoadExternalArrayPointer* instr) {
2850 Register result = ToRegister(instr->result());
2851 Register input = ToRegister(instr->object());
2857 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
2858 Register arguments = ToRegister(instr->arguments());
2859 Register result = ToRegister(instr->result());
2861 if (instr->length()->IsConstantOperand() &&
2862 instr->index()->IsConstantOperand()) {
2863 int32_t const_index = ToInteger32(LConstantOperand::cast(instr->index()));
2864 int32_t const_length = ToInteger32(LConstantOperand::cast(instr->length()));
2868 Register length = ToRegister(instr->length());
2871 if (instr->index()->IsRegister()) {
2872 __ subl(length, ToRegister(instr->index()));
2874 __ subl(length, ToOperand(instr->index()));
2882 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
2883 ElementsKind elements_kind = instr->elements_kind();
2884 LOperand* key = instr->key();
2892 if (instr->hydrogen()->IsDehoisted()) {
2899 instr->elements(),
2903 instr->additional_index()));
2906 XMMRegister result(ToDoubleRegister(instr->result()));
2910 __ movsd(ToDoubleRegister(instr->result()), operand);
2912 Register result(ToRegister(instr->result()));
2932 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
2934 DeoptimizeIf(negative, instr->environment());
2954 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
2955 XMMRegister result(ToDoubleRegister(instr->result()));
2956 LOperand* key = instr->key();
2963 if (instr->hydrogen()->IsDehoisted()) {
2970 if (instr
2974 instr->elements(),
2978 instr->additional_index());
2980 DeoptimizeIf(equal, instr->environment());
2984 instr->elements(),
2988 instr->additional_index());
2993 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
2994 Register result = ToRegister(instr->result());
2995 LOperand* key = instr->key();
3003 if (instr->hydrogen()->IsDehoisted()) {
3012 BuildFastArrayOperand(instr->elements(),
3016 instr->additional_index()));
3019 if (instr->hydrogen()->RequiresHoleCheck()) {
3020 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
3022 DeoptimizeIf(NegateCondition(smi), instr->environment());
3025 DeoptimizeIf(equal, instr->environment());
3031 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
3032 if (instr->is_external()) {
3033 DoLoadKeyedExternalArray(instr);
3034 } else if (instr->hydrogen()->representation().IsDouble()) {
3035 DoLoadKeyedFixedDoubleArray(instr);
3037 DoLoadKeyedFixedArray(instr);
3068 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
3069 ASSERT(ToRegister(instr->object()).is(rdx));
3070 ASSERT(ToRegister(instr->key()).is(rax));
3073 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3077 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
3078 Register result = ToRegister(instr->result());
3080 if (instr->hydrogen()->from_inlined()) {
3105 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
3106 Register result = ToRegister(instr->result());
3111 if (instr->elements()->IsRegister()) {
3112 __ cmpq(rbp, ToRegister(instr->elements()));
3114 __ cmpq(rbp, ToOperand(instr->elements()));
3130 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
3131 Register receiver = ToRegister(instr->receiver());
3132 Register function = ToRegister(instr->function());
3162 DeoptimizeIf(is_smi, instr->environment());
3164 DeoptimizeIf(below, instr->environment());
3178 void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
3179 Register receiver = ToRegister(instr->receiver());
3180 Register function = ToRegister(instr->function());
3181 Register length = ToRegister(instr->length());
3182 Register elements = ToRegister(instr->elements());
3185 ASSERT(ToRegister(instr->result()).is(rax));
3191 DeoptimizeIf(above, instr->environment());
3209 ASSERT(instr->HasPointerMap());
3210 LPointerMap* pointers = instr->pointer_map();
3221 void LCodeGen::DoPushArgument(LPushArgument* instr) {
3222 LOperand* argument = instr->value();
3227 void LCodeGen::DoDrop(LDrop* instr) {
3228 __ Drop(instr->count());
3232 void LCodeGen::DoThisFunction(LThisFunction* instr) {
3233 Register result = ToRegister(instr->result());
3238 void LCodeGen::DoContext(LContext* instr) {
3239 Register result = ToRegister(instr->result());
3244 void LCodeGen::DoOuterContext(LOuterContext* instr) {
3245 Register context = ToRegister(instr->context());
3246 Register result = ToRegister(instr->result());
3252 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
3254 __ PushHeapObject(instr->hydrogen()->pairs());
3255 __ Push(Smi::FromInt(instr->hydrogen()->flags()));
3256 CallRuntime(Runtime::kDeclareGlobals, 3, instr);
3260 void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
3261 Register result = ToRegister(instr->result());
3266 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
3267 Register global = ToRegister(instr->global());
3268 Register result = ToRegister(instr->result());
3276 LInstruction* instr,
3284 LPointerMap* pointers = instr->pointer_map();
3310 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0);
3326 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
3327 ASSERT(ToRegister(instr->result()).is(rax));
3328 CallKnownFunction(instr->hydrogen()->function(),
3329 instr->hydrogen()->formal_parameter_count(),
3330 instr->arity(),
3331 instr,
3337 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3338 Register input_reg = ToRegister(instr->value());
3341 DeoptimizeIf(not_equal, instr->environment());
3363 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
3380 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
3381 Register input_reg = ToRegister(instr->value());
3386 DeoptimizeIf(negative, instr->environment());
3391 void LCodeGen::EmitSmiMathAbs(LMathAbs* instr) {
3392 Register input_reg = ToRegister(instr->value());
3397 DeoptimizeIf(negative, instr->environment());
3402 void LCodeGen::DoMathAbs(LMathAbs* instr) {
3406 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr)
3407 : LDeferredCode(codegen), instr_(instr) { }
3411 virtual LInstruction* instr() { return instr_; }
3416 ASSERT(instr->value()->Equals(instr->result()));
3417 Representation r = instr->hydrogen()->value()->representation();
3421 XMMRegister input_reg = ToDoubleRegister(instr->value());
3426 EmitIntegerMathAbs(instr);
3428 EmitSmiMathAbs(instr);
3431 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
3432 Register input_reg = ToRegister(instr->value());
3435 EmitSmiMathAbs(instr);
3441 void LCodeGen::DoMathFloor(LMathFloor* instr) {
3443 Register output_reg = ToRegister(instr->result());
3444 XMMRegister input_reg = ToDoubleRegister(instr->value());
3448 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3452 instr->environment());
3457 DeoptimizeIf(equal, instr->environment());
3463 DeoptimizeIf(parity_even, instr->environment());
3466 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3472 DeoptimizeIf(not_zero, instr->environment());
3482 DeoptimizeIf(equal, instr->environment());
3493 DeoptimizeIf(overflow, instr->environment());
3500 void LCodeGen::DoMathRound(LMathRound* instr) {
3502 Register output_reg = ToRegister(instr->result());
3503 XMMRegister input_reg = ToDoubleRegister(instr->value());
3519 DeoptimizeIf(equal, instr->environment());
3536 DeoptimizeIf(equal, instr->environment());
3550 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3554 DeoptimizeIf(negative, instr->environment());
3561 void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
3562 XMMRegister input_reg = ToDoubleRegister(instr->value());
3563 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
3568 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
3570 XMMRegister input_reg = ToDoubleRegister(instr->value());
3571 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
3600 void LCodeGen::DoPower(LPower* instr) {
3601 Representation exponent_type = instr->hydrogen()->right()->representation();
3606 ASSERT(!instr->right()->IsRegister() ||
3607 ToRegister(instr->right()).is(exponent));
3608 ASSERT(!instr->right()->IsDoubleRegister() ||
3609 ToDoubleRegister(instr->right()).is(xmm1));
3610 ASSERT(ToDoubleRegister(instr->left()).is(xmm2));
3611 ASSERT(ToDoubleRegister(instr->result()).is(xmm3));
3620 DeoptimizeIf(not_equal, instr->environment());
3635 void LCodeGen::DoRandom(LRandom* instr) {
3638 DeferredDoRandom(LCodeGen* codegen, LRandom* instr)
3639 : LDeferredCode(codegen), instr_(instr) { }
3641 virtual LInstruction* instr() { return instr_; }
3646 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr);
3650 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
3655 ASSERT(ToRegister(instr->global_object()).is(rcx));
3658 ASSERT(ToRegister(instr->global_object()).is(rdi));
3715 void LCodeGen::DoDeferredRandom(LRandom* instr) {
3723 void LCodeGen::DoMathExp(LMathExp* instr) {
3724 XMMRegister input = ToDoubleRegister(instr->value());
3725 XMMRegister result = ToDoubleRegister(instr->result());
3726 Register temp1 = ToRegister(instr->temp1());
3727 Register temp2 = ToRegister(instr->temp2());
3733 void LCodeGen::DoMathLog(LMathLog* instr) {
3734 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
3737 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3741 void LCodeGen::DoMathTan(LMathTan* instr) {
3742 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
3745 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3749 void LCodeGen::DoMathCos(LMathCos* instr) {
3750 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
3753 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3757 void LCodeGen::DoMathSin(LMathSin* instr) {
3758 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
3761 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3765 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
3766 ASSERT(ToRegister(instr->function()).is(rdi));
3767 ASSERT(instr->HasPointerMap());
3769 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
3771 LPointerMap* pointers = instr->pointer_map();
3774 ParameterCount count(instr->arity());
3779 instr->hydrogen()->formal_parameter_count(),
3780 instr->arity(),
3781 instr,
3788 void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
3789 ASSERT(ToRegister(instr->key()).is(rcx));
3790 ASSERT(ToRegister(instr->result()).is(rax));
3792 int arity = instr->arity();
3795 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3800 void LCodeGen::DoCallNamed(LCallNamed* instr) {
3801 ASSERT(ToRegister(instr->result()).is(rax));
3803 int arity = instr->arity();
3807 __ Move(rcx, instr->name());
3808 CallCode(ic, mode, instr);
3813 void LCodeGen::DoCallFunction(LCallFunction* instr) {
3814 ASSERT(ToRegister(instr->function()).is(rdi));
3815 ASSERT(ToRegister(instr->result()).is(rax));
3817 int arity = instr->arity();
3819 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3824 void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
3825 ASSERT(ToRegister(instr->result()).is(rax));
3826 int arity = instr->arity();
3830 __ Move(rcx, instr->name());
3831 CallCode(ic, mode, instr);
3836 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
3837 ASSERT(ToRegister(instr->result()).is(rax));
3838 CallKnownFunction(instr->hydrogen()->target(),
3839 instr->hydrogen()->formal_parameter_count(),
3840 instr->arity(),
3841 instr,
3847 void LCodeGen::DoCallNew(LCallNew* instr) {
3848 ASSERT(ToRegister(instr->constructor()).is(rdi));
3849 ASSERT(ToRegister(instr->result()).is(rax));
3851 __ Set(rax, instr->arity());
3856 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
3860 void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
3861 ASSERT(ToRegister(instr->constructor()).is(rdi));
3862 ASSERT(ToRegister(instr->result()).is(rax));
3864 __ Set(rax, instr->arity());
3865 __ Move(rbx, instr->hydrogen()->property_cell());
3866 ElementsKind kind = instr->hydrogen()->elements_kind();
3873 if (instr->arity() == 0) {
3875 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
3876 } else if (instr->arity() == 1) {
3889 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
3895 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
3899 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
3904 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
3905 CallRuntime(instr->function(), instr->arity(), instr);
3909 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
3910 Register result = ToRegister(instr->result());
3911 Register base = ToRegister(instr->base_object());
3912 __ lea(result, Operand(base, instr->offset()));
3916 instr) {
3917 Representation representation = instr->representation();
3919 HObjectAccess access = instr->hydrogen()->access();
3923 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
3924 Register value = ToRegister(instr->value());
3925 if (instr->object()->IsConstantOperand()) {
3927 LConstantOperand* object = LConstantOperand::cast(instr->object());
3930 Register object = ToRegister(instr->object());
3936 Register object = ToRegister(instr->object());
3937 Handle<Map> transition = instr->transition();
3940 if (instr->value()->IsConstantOperand()) {
3941 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
3943 DeoptimizeIf(no_condition, instr->environment());
3947 if (instr->value()->IsConstantOperand()) {
3948 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
3950 DeoptimizeIf(no_condition, instr->environment());
3953 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
3954 Register value = ToRegister(instr->value());
3956 DeoptimizeIf(cc, instr->environment());
3962 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
3963 XMMRegister value = ToDoubleRegister(instr->value());
3969 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) {
3972 Register temp = ToRegister(instr->temp());
3988 instr->hydrogen()->value()->IsHeapObject()
3993 write_register = ToRegister(instr->temp());
3997 if (instr->value()->IsConstantOperand()) {
3998 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4004 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4008 __ movq(FieldOperand(write_register, offset), ToRegister(instr->value()));
4011 if (instr->hydrogen()->NeedsWriteBarrier()) {
4012 Register value = ToRegister(instr->value());
4013 Register temp = access.IsInobject() ? ToRegister(instr->temp()) : object;
4026 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
4027 ASSERT(ToRegister(instr->object()).is(rdx));
4028 ASSERT(ToRegister(instr->value()).is(rax));
4030 __ Move(rcx, instr->hydrogen()->name());
4031 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
4034 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4050 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
4051 if (instr->hydrogen()->skip_check()) return;
4053 if (instr->length()->IsRegister()) {
4054 Register reg = ToRegister(instr->length());
4055 if (!instr->hydrogen()->length()->representation().IsSmi()) {
4058 if (instr->index()->IsConstantOperand()) {
4060 ToInteger32(LConstantOperand::cast(instr->index()));
4061 if (instr->hydrogen()->length()->representation().IsSmi()) {
4067 Register reg2 = ToRegister(instr->index());
4068 if (!instr->hydrogen()->index()->representation().IsSmi()) {
4074 Operand length = ToOperand(instr->length());
4075 if (instr->index()->IsConstantOperand()) {
4077 ToInteger32(LConstantOperand::cast(instr->index()));
4078 if (instr->hydrogen()->length()->representation().IsSmi()) {
4084 __ cmpq(length, ToRegister(instr->index()));
4088 instr->hydrogen()->allow_equality() ? below : below_equal;
4089 ApplyCheckIf(condition, instr);
4093 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4094 ElementsKind elements_kind = instr->elements_kind();
4095 LOperand* key = instr->key();
4103 if (instr->hydrogen()->IsDehoisted()) {
4110 instr->elements(),
4114 instr->additional_index()));
4117 XMMRegister value(ToDoubleRegister(instr->value()));
4121 __ movsd(operand, ToDoubleRegister(instr->value()));
4123 Register value(ToRegister(instr->value()));
4155 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
4156 XMMRegister value = ToDoubleRegister(instr->value());
4157 LOperand* key = instr->key();
4165 if (instr->hydrogen()->IsDehoisted()) {
4172 if (instr->NeedsCanonicalization()) {
4186 instr->elements(),
4190 instr->additional_index());
4196 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4197 Register elements = ToRegister(instr->elements());
4198 LOperand* key = instr->key();
4206 if (instr->hydrogen()->IsDehoisted()) {
4214 BuildFastArrayOperand(instr->elements(),
4218 instr->additional_index());
4219 if (instr->value()->IsRegister()) {
4220 __ movq(operand, ToRegister(instr->value()));
4222 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4232 if (instr->hydrogen()->NeedsWriteBarrier()) {
4233 ASSERT(instr->value()->IsRegister());
4234 Register value = ToRegister(instr->value());
4235 ASSERT(!instr->key()->IsConstantOperand());
4237 instr->hydrogen()->value()->IsHeapObject()
4252 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
4253 if (instr->is_external()) {
4254 DoStoreKeyedExternalArray(instr);
4255 } else if (instr->hydrogen()->value()->representation().IsDouble()) {
4256 DoStoreKeyedFixedDoubleArray(instr);
4258 DoStoreKeyedFixedArray(instr);
4263 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
4264 ASSERT(ToRegister(instr->object()).is(rdx));
4265 ASSERT(ToRegister(instr->key()).is(rcx));
4266 ASSERT(ToRegister(instr->value()).is(rax));
4268 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
4271 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4275 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
4276 Register object_reg = ToRegister(instr->object());
4278 Handle<Map> from_map = instr->original_map();
4279 Handle<Map> to_map = instr->transitioned_map();
4280 ElementsKind from_kind = instr->from_kind();
4281 ElementsKind to_kind = instr->to_kind();
4287 Register new_map_reg = ToRegister(instr->new_map_temp());
4291 ASSERT_NE(instr->temp(), NULL);
4293 ToRegister(instr->temp()), kDontSaveFPRegs);
4303 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4309 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
4310 Register object = ToRegister(instr->object());
4311 Register temp = ToRegister(instr->temp());
4313 DeoptimizeIf(equal, instr->environment());
4317 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4318 EmitPushTaggedOperand(instr->left());
4319 EmitPushTaggedOperand(instr->right());
4320 StringAddStub stub(instr->hydrogen()->flags());
4321 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4325 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
4328 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
4329 : LDeferredCode(codegen), instr_(instr) { }
4331 virtual LInstruction* instr() { return instr_; }
4337 new(zone()) DeferredStringCharCodeAt(this, instr);
4340 ToRegister(instr->string()),
4341 ToRegister(instr->index()),
4342 ToRegister(instr->result()),
4348 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
4349 Register string = ToRegister(instr->string());
4350 Register result = ToRegister(instr->result());
4362 if (instr->index()->IsConstantOperand()) {
4363 int32_t const_index = ToInteger32(LConstantOperand::cast(instr->index()));
4366 Register index = ToRegister(instr->index());
4370 CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, instr);
4377 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
4380 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
4381 instr) { }
4383 virtual LInstruction* instr() { return instr_; }
4389 new(zone()) DeferredStringCharFromCode(this, instr);
4391 ASSERT(instr->hydrogen()->value()->representation().IsInteger32());
4392 Register char_code = ToRegister(instr->char_code());
4393 Register result = ToRegister(instr->result());
4409 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
4410 Register char_code = ToRegister(instr->char_code());
4411 Register result = ToRegister(instr->result());
4421 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr);
4426 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4427 LOperand* input = instr->value();
4429 LOperand* output = instr->result();
4439 void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) {
4440 LOperand* input = instr->value();
4442 LOperand* output = instr->result();
4444 if (!instr->hydrogen()->value()->HasRange() ||
4445 !instr->hydrogen()->value()->range()->IsInSmiRange()) {
4446 DeoptimizeIf(overflow, instr->environment());
4451 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4452 LOperand* input = instr->value();
4453 LOperand* output = instr->result();
4454 LOperand* temp = instr->temp();
4462 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4463 LOperand* input = instr->value();
4464 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4471 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4474 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
4475 : LDeferredCode(codegen), instr_(instr) { }
4479 virtual LInstruction* instr() { return instr_; }
4484 LOperand* input = instr->value();
4485 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4488 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4496 void LCodeGen::DoDeferredNumberTagU(LNumberTagU* instr) {
4498 Register reg = ToRegister(instr->value());
4523 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
4534 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
4537 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4538 : LDeferredCode(codegen), instr_(instr) { }
4540 virtual LInstruction* instr() { return instr_; }
4545 XMMRegister input_reg = ToDoubleRegister(instr->value());
4546 Register reg = ToRegister(instr->result());
4547 Register tmp = ToRegister(instr->temp());
4549 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4560 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
4564 Register reg = ToRegister(instr->result());
4569 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
4577 void LCodeGen::DoSmiTag(LSmiTag* instr) {
4578 ASSERT(instr->value()->Equals(instr->result()));
4579 Register input = ToRegister(instr->value());
4580 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
4585 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
4586 ASSERT(instr->value()->Equals(instr->result()));
4587 Register input = ToRegister(instr->value());
4588 if (instr->needs_check()) {
4590 DeoptimizeIf(NegateCondition(is_smi), instr->environment());
4654 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
4656 Register input_reg = ToRegister(instr->value());
4662 if (instr->truncating()) {
4667 DeoptimizeIf(not_equal, instr->environment());
4677 DeoptimizeIf(equal, instr->environment());
4680 DeoptimizeIf(not_equal, instr->environment());
4682 XMMRegister xmm_temp = ToDoubleRegister(instr->temp());
4687 DeoptimizeIf(not_equal, instr->environment());
4688 DeoptimizeIf(parity_even, instr->environment()); // NaN.
4689 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
4694 DeoptimizeIf(not_zero, instr->environment());
4701 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
4704 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
4705 : LDeferredCode(codegen), instr_(instr) { }
4707 virtual LInstruction* instr() { return instr_; }
4712 LOperand* input = instr->value();
4714 ASSERT(input->Equals(instr->result()));
4717 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
4724 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
4725 LOperand* input = instr->value();
4727 LOperand* result = instr->result();
4733 HValue* value = instr->hydrogen()->value();
4738 instr->hydrogen()->can_convert_undefined_to_nan(),
4739 instr->hydrogen()->deoptimize_on_minus_zero(),
4740 instr->environment(),
4745 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
4746 LOperand* input = instr->value();
4748 LOperand* result = instr->result();
4754 if (instr->truncating()) {
4762 DeoptimizeIf(equal, instr->environment());
4767 DeoptimizeIf(not_equal, instr->environment());
4768 DeoptimizeIf(parity_even, instr->environment()); // NaN.
4769 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
4780 DeoptimizeIf(not_zero, instr->environment());
4787 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
4788 LOperand* input = instr->value();
4790 LOperand* result = instr->result();
4801 DeoptimizeIf(not_equal, instr->environment());
4802 DeoptimizeIf(parity_even, instr->environment()); // NaN.
4804 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
4814 DeoptimizeIf(not_zero, instr->environment());
4818 DeoptimizeIf(overflow, instr->environment());
4822 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
4823 LOperand* input = instr->value();
4825 DeoptimizeIf(NegateCondition(cc), instr->environment());
4829 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
4830 if (!instr->hydrogen()->value()->IsHeapObject()) {
4831 LOperand* input = instr->value();
4833 DeoptimizeIf(cc, instr->environment());
4838 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
4839 Register input = ToRegister(instr->value());
4843 if (instr->hydrogen()->is_interval_check()) {
4846 instr->hydrogen()->GetCheckInterval(&first, &last);
4853 DeoptimizeIf(not_equal, instr->environment());
4855 DeoptimizeIf(below, instr->environment());
4860 DeoptimizeIf(above, instr->environment());
4866 instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
4872 DeoptimizeIf(tag == 0 ? not_zero : zero, instr->environment());
4878 DeoptimizeIf(not_equal, instr->environment());
4884 void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
4885 Register reg = ToRegister(instr->value());
4886 Handle<JSFunction> target = instr->hydrogen()->target();
4888 DeoptimizeIf(not_equal, instr->environment());
4892 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
4896 CallRuntimeFromDeferred(Runtime::kMigrateInstance, 1, instr);
4899 DeoptimizeIf(zero, instr->environment());
4903 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
4906 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object)
4907 : LDeferredCode(codegen), instr_(instr), object_(object) {
4914 virtual LInstruction* instr() { return instr_; }
4921 if (instr->hydrogen()->CanOmitMapChecks()) return;
4923 LOperand* input = instr->value();
4927 SmallMapList* map_set = instr->hydrogen()->map_set();
4930 if (instr->hydrogen()->has_migration_target()) {
4931 deferred = new(zone()) DeferredCheckMaps(this, instr, reg);
4944 if (instr->hydrogen()->has_migration_target()) {
4947 DeoptimizeIf(not_equal, instr->environment());
4954 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
4955 XMMRegister value_reg = ToDoubleRegister(instr->unclamped());
4956 Register result_reg = ToRegister(instr->result());
4961 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
4962 ASSERT(instr->unclamped()->Equals(instr->result()));
4963 Register value_reg = ToRegister(instr->result());
4968 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
4969 ASSERT(instr->unclamped()->Equals(instr->result()));
4970 Register input_reg = ToRegister(instr->unclamped());
4971 XMMRegister temp_xmm_reg = ToDoubleRegister(instr->temp_xmm());
4984 DeoptimizeIf(not_equal, instr->environment());
5003 void LCodeGen::DoAllocate(LAllocate* instr) {
5006 DeferredAllocate(LCodeGen* codegen, LAllocate* instr)
5007 : LDeferredCode(codegen), instr_(instr) { }
5009 virtual LInstruction* instr() { return instr_; }
5015 new(zone()) DeferredAllocate(this, instr);
5017 Register result = ToRegister(instr->result());
5018 Register temp = ToRegister(instr->temp());
5022 if (instr->hydrogen()->MustAllocateDoubleAligned()) {
5025 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5026 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation());
5027 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5029 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5030 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5034 if (instr->size()->IsConstantOperand()) {
5035 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5038 Register size = ToRegister(instr->size());
5044 if (instr->hydrogen()->MustPrefillWithFiller()) {
5045 if (instr->size()->IsConstantOperand()) {
5046 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5049 temp = ToRegister(instr->size());
5063 void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
5064 Register result = ToRegister(instr->result());
5072 if (instr->size()->IsRegister()) {
5073 Register size = ToRegister(instr->size());
5078 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5082 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5083 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation());
5084 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5085 CallRuntimeFromDeferred(Runtime::kAllocateInOldPointerSpace, 1, instr);
5086 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5087 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5088 CallRuntimeFromDeferred(Runtime::kAllocateInOldDataSpace, 1, instr);
5090 CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr);
5096 void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
5097 ASSERT(ToRegister(instr->value()).is(rax));
5099 CallRuntime(Runtime::kToFastProperties, 1, instr);
5103 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
5110 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
5111 __ LoadHeapObject(rcx, instr->hydrogen()->literals());
5119 __ Push(Smi::FromInt(instr->hydrogen()->literal_index()));
5120 __ Push(instr->hydrogen()->pattern());
5121 __ Push(instr->hydrogen()->flags());
5122 CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr);
5134 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr);
5153 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
5156 bool pretenure = instr->hydrogen()->pretenure();
5157 if (!pretenure && instr->hydrogen()->has_no_literals()) {
5158 FastNewClosureStub stub(instr->hydrogen()->language_mode(),
5159 instr->hydrogen()->is_generator());
5160 __ Push(instr->hydrogen()->shared_info());
5161 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
5164 __ Push(instr->hydrogen()->shared_info());
5167 CallRuntime(Runtime::kNewClosure, 3, instr);
5172 void LCodeGen::DoTypeof(LTypeof* instr) {
5173 LOperand* input = instr->value();
5175 CallRuntime(Runtime::kTypeof, 1, instr);
5197 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
5198 Register input = ToRegister(instr->value());
5201 EmitTypeofIs(instr->TrueLabel(chunk_),
5202 instr->FalseLabel(chunk_), input, instr->type_literal());
5204 EmitBranch(instr, final_branch_condition);
5285 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
5286 Register temp = ToRegister(instr->temp());
5289 EmitBranch(instr, equal);
5323 void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
5326 ASSERT(instr->HasEnvironment());
5327 LEnvironment* env = instr->environment();
5333 void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
5334 Deoptimizer::BailoutType type = instr->hydrogen()->type();
5343 Comment(";;; deoptimize: %s", instr->hydrogen()->reason());
5344 DeoptimizeIf(no_condition, instr->environment(), type);
5348 void LCodeGen::DoDummyUse(LDummyUse* instr) {
5353 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
5357 RecordSafepointWithLazyDeopt(instr
5358 ASSERT(instr->HasEnvironment());
5359 LEnvironment* env = instr->environment();
5364 void LCodeGen::DoStackCheck(LStackCheck* instr) {
5367 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
5368 : LDeferredCode(codegen), instr_(instr) { }
5370 virtual LInstruction* instr() { return instr_; }
5375 ASSERT(instr->HasEnvironment());
5376 LEnvironment* env = instr->environment();
5379 if (instr->hydrogen()->is_function_entry()) {
5385 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
5392 ASSERT(instr->hydrogen()->is_backwards_branch());
5395 new(zone()) DeferredStackCheck(this, instr);
5400 __ bind(instr->done_label());
5401 deferred_stack_check->SetExit(instr->done_label());
5410 void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
5414 LEnvironment* environment = instr->environment();
5427 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
5429 DeoptimizeIf(equal, instr->environment());
5434 DeoptimizeIf(equal, instr->environment());
5437 DeoptimizeIf(cc, instr->environment());
5441 DeoptimizeIf(below_equal, instr->environment());
5452 CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr);
5456 DeoptimizeIf(not_equal, instr->environment());
5461 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) {
5462 Register map = ToRegister(instr->map());
5463 Register result = ToRegister(instr->result());
5475 FieldOperand(result, FixedArray::SizeFor(instr->idx())));
5478 DeoptimizeIf(cc, instr->environment());
5482 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
5483 Register object = ToRegister(instr->value());
5484 __ cmpq(ToRegister(instr->map()),
5486 DeoptimizeIf(not_equal, instr->environment());
5490 void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
5491 Register object = ToRegister(instr->object());
5492 Register index = ToRegister(instr->index());