Lines Matching refs:instr

263 void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
264 if (instr->IsCall()) {
267 if (!instr->IsLazyBailout() && !instr->IsGap()) {
273 void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) {
274 if (FLAG_debug_code && FLAG_enable_slow_asserts && instr->HasResult() &&
275 instr->hydrogen_value()->representation().IsInteger32() &&
276 instr->result()->IsRegister()) {
277 __ AssertZeroExtended(ToRegister(instr->result()));
280 if (instr->HasResult() && instr->MustSignExtendResult(chunk())) {
286 if (instr->result()->IsRegister()) {
287 Register result_reg = ToRegister(instr->result());
291 DCHECK(instr->result()->IsStackSlot());
292 Operand src = ToOperand(instr->result());
356 code->instr()->hydrogen_value()->id(),
357 code->instr()->Mnemonic());
624 LInstruction* instr,
627 DCHECK(instr != NULL);
629 RecordSafepointWithLazyDeopt(instr, safepoint_mode, argc);
642 LInstruction* instr) {
643 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT, 0);
649 LInstruction* instr,
651 DCHECK(instr != NULL);
652 DCHECK(instr->HasPointerMap());
656 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0);
680 LInstruction* instr,
686 instr->pointer_map(), argc, Safepoint::kNoLazyDeopt);
727 void LCodeGen::DeoptimizeIf(Condition cc, LInstruction* instr,
730 LEnvironment* environment = instr->environment();
773 Deoptimizer::Reason reason(instr->hydrogen_value()->position().raw(),
774 instr->Mnemonic(), detail);
800 void LCodeGen::DeoptimizeIf(Condition cc, LInstruction* instr,
805 DeoptimizeIf(cc, instr, detail, bailout_type);
880 LInstruction* instr, SafepointMode safepoint_mode, int argc) {
882 RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt);
886 instr->pointer_map(), argc, Safepoint::kLazyDeopt);
974 void LCodeGen::DoInstructionGap(LInstructionGap* instr) {
975 DoGap(instr);
979 void LCodeGen::DoParameter(LParameter* instr) {
984 void LCodeGen::DoCallStub(LCallStub* instr) {
985 DCHECK(ToRegister(instr->context()).is(rsi));
986 DCHECK(ToRegister(instr->result()).is(rax));
987 switch (instr->hydrogen()->major_key()) {
990 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
995 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1000 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1009 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
1014 void LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) {
1015 Register dividend = ToRegister(instr->dividend());
1016 int32_t divisor = instr->divisor();
1017 DCHECK(dividend.is(ToRegister(instr->result())));
1025 HMod* hmod = instr->hydrogen();
1036 DeoptimizeIf(zero, instr, "minus zero");
1047 void LCodeGen::DoModByConstI(LModByConstI* instr) {
1048 Register dividend = ToRegister(instr->dividend());
1049 int32_t divisor = instr->divisor();
1050 DCHECK(ToRegister(instr->result()).is(rax));
1053 DeoptimizeIf(no_condition, instr, "division by zero");
1063 HMod* hmod = instr->hydrogen();
1068 DeoptimizeIf(less, instr, "minus zero");
1074 void LCodeGen::DoModI(LModI* instr) {
1075 HMod* hmod = instr->hydrogen();
1077 Register left_reg = ToRegister(instr->left());
1079 Register right_reg = ToRegister(instr->right());
1082 Register result_reg = ToRegister(instr->result());
1090 DeoptimizeIf(zero, instr, "division by zero");
1101 DeoptimizeIf(equal, instr, "minus zero");
1121 DeoptimizeIf(zero, instr, "minus zero");
1130 void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
1131 Register dividend = ToRegister(instr->dividend());
1132 int32_t divisor = instr->divisor();
1133 DCHECK(dividend.is(ToRegister(instr->result())));
1146 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1147 DeoptimizeIf(zero, instr, "minus zero");
1152 if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
1153 DeoptimizeIf(overflow, instr, "overflow");
1159 if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
1174 void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
1175 Register dividend = ToRegister(instr->dividend());
1176 int32_t divisor = instr->divisor();
1177 DCHECK(ToRegister(instr->result()).is(rdx));
1180 DeoptimizeIf(no_condition, instr, "division by zero");
1185 HMathFloorOfDiv* hdiv = instr->hydrogen();
1188 DeoptimizeIf(zero, instr, "minus zero");
1202 Register temp = ToRegister(instr->temp3());
1220 void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) {
1221 HBinaryOperation* hdiv = instr->hydrogen();
1222 Register dividend = ToRegister(instr->dividend());
1223 Register divisor = ToRegister(instr->divisor());
1224 Register remainder = ToRegister(instr->temp());
1225 Register result = ToRegister(instr->result());
1235 DeoptimizeIf(zero, instr, "division by zero");
1244 DeoptimizeIf(sign, instr, "minus zero");
1254 DeoptimizeIf(zero, instr, "overflow");
1272 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
1273 Register dividend = ToRegister(instr->dividend());
1274 int32_t divisor = instr->divisor();
1275 Register result = ToRegister(instr->result());
1280 HDiv* hdiv = instr->hydrogen();
1283 DeoptimizeIf(zero, instr, "minus zero");
1288 DeoptimizeIf(zero, instr, "overflow");
1295 DeoptimizeIf(not_zero, instr, "lost precision");
1310 void LCodeGen::DoDivByConstI(LDivByConstI* instr) {
1311 Register dividend = ToRegister(instr->dividend());
1312 int32_t divisor = instr->divisor();
1313 DCHECK(ToRegister(instr->result()).is(rdx));
1316 DeoptimizeIf(no_condition, instr, "division by zero");
1321 HDiv* hdiv = instr->hydrogen();
1324 DeoptimizeIf(zero, instr, "minus zero");
1334 DeoptimizeIf(not_equal, instr, "lost precision");
1340 void LCodeGen::DoDivI(LDivI* instr) {
1341 HBinaryOperation* hdiv = instr->hydrogen();
1342 Register dividend = ToRegister(instr->dividend());
1343 Register divisor = ToRegister(instr->divisor());
1344 Register remainder = ToRegister(instr->temp());
1347 DCHECK(ToRegister(instr->result()).is(rax));
1354 DeoptimizeIf(zero, instr, "division by zero");
1363 DeoptimizeIf(sign, instr, "minus zero");
1373 DeoptimizeIf(zero, instr, "overflow");
1384 DeoptimizeIf(not_zero, instr, "lost precision");
1389 void LCodeGen::DoMulI(LMulI* instr) {
1390 Register left = ToRegister(instr->left());
1391 LOperand* right = instr->right();
1393 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1394 if (instr->hydrogen_value()->representation().IsSmi()) {
1402 instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1445 if (instr->hydrogen_value()->representation().IsSmi()) {
1452 if (instr->hydrogen_value()->representation().IsSmi()) {
1461 DeoptimizeIf(overflow, instr, "overflow");
1464 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1467 if (instr->hydrogen_value()->representation().IsSmi()) {
1477 ? !instr->hydrogen_value()->representation().IsSmi()
1480 DeoptimizeIf(no_condition, instr, "minus zero");
1483 DeoptimizeIf(less, instr, "minus zero");
1486 if (instr->hydrogen_value()->representation().IsSmi()) {
1491 DeoptimizeIf(sign, instr, "minus zero");
1494 if (instr->hydrogen_value()->representation().IsSmi()) {
1499 DeoptimizeIf(sign, instr, "minus zero");
1506 void LCodeGen::DoBitI(LBitI* instr) {
1507 LOperand* left = instr->left();
1508 LOperand* right = instr->right();
1509 DCHECK(left->Equals(instr->result()));
1515 instr->hydrogen()->right()->representation());
1516 switch (instr->op()) {
1535 switch (instr->op()) {
1537 if (instr->IsInteger32()) {
1544 if (instr->IsInteger32()) {
1551 if (instr->IsInteger32()) {
1563 switch (instr->op()) {
1565 if (instr->IsInteger32()) {
1572 if (instr->IsInteger32()) {
1579 if (instr->IsInteger32()) {
1593 void LCodeGen::DoShiftI(LShiftI* instr) {
1594 LOperand* left = instr->left();
1595 LOperand* right = instr->right();
1596 DCHECK(left->Equals(instr->result()));
1601 switch (instr->op()) {
1610 if (instr->can_deopt()) {
1612 DeoptimizeIf(negative, instr, "negative value");
1625 switch (instr->op()) {
1639 } else if (instr->can_deopt()) {
1641 DeoptimizeIf(negative, instr, "negative value");
1646 if (instr->hydrogen_value()->representation().IsSmi()) {
1651 if (instr->can_deopt()) {
1656 DeoptimizeIf(overflow, instr, "overflow");
1674 void LCodeGen::DoSubI(LSubI* instr) {
1675 LOperand* left = instr->left();
1676 LOperand* right = instr->right();
1677 DCHECK(left->Equals(instr->result()));
1682 instr->hydrogen()->right()->representation());
1685 if (instr->hydrogen_value()->representation().IsSmi()) {
1691 if (instr->hydrogen_value()->representation().IsSmi()) {
1698 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1699 DeoptimizeIf(overflow, instr, "overflow");
1704 void LCodeGen::DoConstantI(LConstantI* instr) {
1705 Register dst = ToRegister(instr->result());
1706 if (instr->value() == 0) {
1709 __ movl(dst, Immediate(instr->value()));
1714 void LCodeGen::DoConstantS(LConstantS* instr) {
1715 __ Move(ToRegister(instr->result()), instr->value());
1719 void LCodeGen::DoConstantD(LConstantD* instr) {
1720 DCHECK(instr->result()->IsDoubleRegister());
1721 XMMRegister res = ToDoubleRegister(instr->result());
1722 double v = instr->value();
1729 Register tmp = ToRegister(instr->temp());
1736 void LCodeGen::DoConstantE(LConstantE* instr) {
1737 __ LoadAddress(ToRegister(instr->result()), instr->value());
1741 void LCodeGen::DoConstantT(LConstantT* instr) {
1742 Handle<Object> object = instr->value(isolate());
1744 __ Move(ToRegister(instr->result()), object);
1748 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1749 Register result = ToRegister(instr->result());
1750 Register map = ToRegister(instr->value());
1755 void LCodeGen::DoDateField(LDateField* instr) {
1756 Register object = ToRegister(instr->date());
1757 Register result = ToRegister(instr->result());
1758 Smi* index = instr->index();
1764 DeoptimizeIf(cc, instr, "Smi");
1766 DeoptimizeIf(not_equal, instr, "not a date object");
1810 void LCodeGen::DoSeqStringGetChar(LSeqStringGetChar* instr) {
1811 String::Encoding encoding = instr->hydrogen()->encoding();
1812 Register result = ToRegister(instr->result());
1813 Register string = ToRegister(instr->string());
1829 Operand operand = BuildSeqStringOperand(string, instr->index(), encoding);
1838 void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
1839 String::Encoding encoding = instr->hydrogen()->encoding();
1840 Register string = ToRegister(instr->string());
1843 Register value = ToRegister(instr->value());
1844 Register index = ToRegister(instr->index());
1848 instr->hydrogen()->encoding() == String::ONE_BYTE_ENCODING
1853 Operand operand = BuildSeqStringOperand(string, instr->index(), encoding);
1854 if (instr->value()->IsConstantOperand()) {
1855 int value = ToInteger32(LConstantOperand::cast(instr->value()));
1865 Register value = ToRegister(instr->value());
1875 void LCodeGen::DoAddI(LAddI* instr) {
1876 LOperand* left = instr->left();
1877 LOperand* right = instr->right();
1879 Representation target_rep = instr->hydrogen()->representation();
1882 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) {
1888 instr->hydrogen()->right()->representation());
1890 __ leap(ToRegister(instr->result()),
1893 __ leal(ToRegister(instr->result()),
1899 __ leap(ToRegister(instr->result()), address);
1901 __ leal(ToRegister(instr->result()), address);
1910 instr->hydrogen()->right()->representation());
1929 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1930 DeoptimizeIf(overflow, instr, "overflow");
1936 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
1937 LOperand* left = instr->left();
1938 LOperand* right = instr->right();
1939 DCHECK(left->Equals(instr->result()));
1940 HMathMinMax::Operation operation = instr->hydrogen()->operation();
1941 if (instr->hydrogen()->representation().IsSmiOrInteger32()) {
1950 instr->hydrogen()->right()->representation()));
1952 ? !instr->hydrogen()->representation().IsSmi()
1959 if (instr->hydrogen_value()->representation().IsSmi()) {
1968 if (instr->hydrogen_value()->representation().IsSmi()) {
1978 DCHECK(instr->hydrogen()->representation().IsDouble());
2014 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
2015 XMMRegister left = ToDoubleRegister(instr->left());
2016 XMMRegister right = ToDoubleRegister(instr->right());
2017 XMMRegister result = ToDoubleRegister(instr->result());
2019 DCHECK(instr->op() == Token::MOD || left.is(result));
2020 switch (instr->op()) {
2053 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
2054 DCHECK(ToRegister(instr->context()).is(rsi));
2055 DCHECK(ToRegister(instr->left()).is(rdx));
2056 DCHECK(ToRegister(instr->right()).is(rax));
2057 DCHECK(ToRegister(instr->result()).is(rax));
2060 CodeFactory::BinaryOpIC(isolate(), instr->op(), NO_OVERWRITE).code();
2061 CallCode(code, RelocInfo::CODE_TARGET, instr);
2066 void LCodeGen::EmitBranch(InstrType instr, Condition cc) {
2067 int left_block = instr->TrueDestination(chunk_);
2068 int right_block = instr->FalseDestination(chunk_);
2088 void LCodeGen::EmitFalseBranch(InstrType instr, Condition cc) {
2089 int false_block = instr->FalseDestination(chunk_);
2094 void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
2099 void LCodeGen::DoBranch(LBranch* instr) {
2100 Representation r = instr->hydrogen()->value()->representation();
2103 Register reg = ToRegister(instr->value());
2105 EmitBranch(instr, not_zero);
2108 Register reg = ToRegister(instr->value());
2110 EmitBranch(instr, not_zero);
2113 XMMRegister reg = ToDoubleRegister(instr->value());
2117 EmitBranch(instr, not_equal);
2120 Register reg = ToRegister(instr->value());
2121 HType type = instr->hydrogen()->value()->type();
2125 EmitBranch(instr, equal);
2129 EmitBranch(instr, not_equal);
2132 EmitBranch(instr, no_condition);
2138 EmitBranch(instr, not_equal);
2142 EmitBranch(instr, not_equal);
2144 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
2151 __ j(equal, instr->FalseLabel(chunk_));
2156 __ j(equal, instr->TrueLabel(chunk_));
2159 __ j(equal, instr->FalseLabel(chunk_));
2164 __ j(equal, instr->FalseLabel(chunk_));
2170 __ j(equal, instr->FalseLabel(chunk_));
2171 __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
2175 DeoptimizeIf(zero, instr, "Smi");
2186 __ j(not_zero, instr->FalseLabel(chunk_));
2193 __ j(above_equal, instr->TrueLabel(chunk_));
2202 __ j(not_zero, instr->TrueLabel(chunk_));
2203 __ jmp(instr->FalseLabel(chunk_));
2210 __ j(equal, instr->TrueLabel(chunk_));
2221 __ j(zero, instr->FalseLabel(chunk_));
2222 __ jmp(instr->TrueLabel(chunk_));
2229 DeoptimizeIf(no_condition, instr, "unexpected object");
2243 void LCodeGen::DoGoto(LGoto* instr) {
2244 EmitGoto(instr->block_id());
2280 void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) {
2281 LOperand* left = instr->left();
2282 LOperand* right = instr->right();
2284 instr->is_double() ||
2285 instr->hydrogen()->left()->CheckFlag(HInstruction::kUint32) ||
2286 instr->hydrogen()->right()->CheckFlag(HInstruction::kUint32);
2287 Condition cc = TokenToCondition(instr->op(), is_unsigned);
2293 int next_block = EvalComparison(instr->op(), left_val, right_val) ?
2294 instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_);
2297 if (instr->is_double()) {
2301 __ j(parity_even, instr->FalseLabel(chunk_));
2306 if (instr->hydrogen_value()->representation().IsSmi()) {
2313 if (instr->hydrogen_value()->representation().IsSmi()) {
2326 } else if (instr->hydrogen_value()->representation().IsSmi()) {
2340 EmitBranch(instr, cc);
2345 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
2346 Register left = ToRegister(instr->left());
2348 if (instr->right()->IsConstantOperand()) {
2349 Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right()));
2352 Register right = ToRegister(instr->right());
2355 EmitBranch(instr, equal);
2359 void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
2360 if (instr->hydrogen()->representation().IsTagged()) {
2361 Register input_reg = ToRegister(instr->object());
2363 EmitBranch(instr, equal);
2367 XMMRegister input_reg = ToDoubleRegister(instr->object());
2369 EmitFalseBranch(instr, parity_odd);
2377 EmitBranch(instr, equal);
2381 void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
2382 Representation rep = instr->hydrogen()->value()->representation();
2386 XMMRegister value = ToDoubleRegister(instr->value());
2390 EmitFalseBranch(instr, not_equal);
2393 EmitBranch(instr, not_zero);
2395 Register value = ToRegister(instr->value());
2397 __ CheckMap(value, map, instr->FalseLabel(chunk()), DO_SMI_CHECK);
2400 EmitFalseBranch(instr, no_overflow);
2403 EmitBranch(instr, equal);
2433 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
2434 Register reg = ToRegister(instr->value());
2437 reg, instr->FalseLabel(chunk_), instr->TrueLabel(chunk_));
2439 EmitBranch(instr, true_cond);
2457 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
2458 Register reg = ToRegister(instr->value());
2459 Register temp = ToRegister(instr->temp());
2462 instr->hydrogen()->value()->type().IsHeapObject()
2466 reg, temp, instr->FalseLabel(chunk_), check_needed);
2468 EmitBranch(instr, true_cond);
2472 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
2474 if (instr->value()->IsRegister()) {
2475 Register input = ToRegister(instr->value());
2478 Operand input = ToOperand(instr->value());
2481 EmitBranch(instr, is_smi);
2485 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
2486 Register input = ToRegister(instr->value());
2487 Register temp = ToRegister(instr->temp());
2489 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
2490 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2495 EmitBranch(instr, not_zero);
2499 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
2500 DCHECK(ToRegister(instr->context()).is(rsi));
2501 Token::Value op = instr->op();
2504 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2509 EmitBranch(instr, condition);
2513 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
2514 InstanceType from = instr->from();
2515 InstanceType to = instr->to();
2522 static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
2523 InstanceType from = instr->from();
2524 InstanceType to = instr->to();
2533 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
2534 Register input = ToRegister(instr->value());
2536 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
2537 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2540 __ CmpObjectType(input, TestType(instr->hydrogen()), kScratchRegister);
2541 EmitBranch(instr, BranchCondition(instr->hydrogen()));
2545 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
2546 Register input = ToRegister(instr->value());
2547 Register result = ToRegister(instr->result());
2558 LHasCachedArrayIndexAndBranch* instr) {
2559 Register input = ToRegister(instr->value());
2563 EmitBranch(instr, equal);
2635 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2636 Register input = ToRegister(instr->value());
2637 Register temp = ToRegister(instr->temp());
2638 Register temp2 = ToRegister(instr->temp2());
2639 Handle<String> class_name = instr->hydrogen()->class_name();
2641 EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
2644 EmitBranch(instr, equal);
2648 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
2649 Register reg = ToRegister(instr->value());
2651 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map());
2652 EmitBranch(instr, equal);
2656 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
2657 DCHECK(ToRegister(instr->context()).is(rsi));
2659 __ Push(ToRegister(instr->left()));
2660 __ Push(ToRegister(instr->right()));
2661 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2665 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
2668 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex);
2673 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
2677 LInstanceOfKnownGlobal* instr)
2678 : LDeferredCode(codegen), instr_(instr) { }
2682 virtual LInstruction* instr() OVERRIDE { return instr_; }
2689 DCHECK(ToRegister(instr->context()).is(rsi));
2691 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
2694 Register object = ToRegister(instr->value());
2704 Register map = ToRegister(instr->temp());
2712 __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex);
2731 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
2738 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
2746 __ Push(ToRegister(instr->value()));
2747 __ Push(instr->function());
2761 instr,
2765 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment();
2783 void LCodeGen::DoCmpT(LCmpT* instr) {
2784 DCHECK(ToRegister(instr->context()).is(rsi));
2785 Token::Value op = instr->op();
2788 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2794 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
2797 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex);
2802 void LCodeGen::DoReturn(LReturn* instr) {
2821 if (instr->has_constant_parameter_count()) {
2822 __ Ret((ToInteger32(instr->constant_parameter_count()) + 1) * kPointerSize,
2825 Register reg = ToRegister(instr->parameter_count());
2840 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
2841 Register result = ToRegister(instr->result());
2842 __ LoadGlobalCell(result, instr->hydrogen()->cell().handle());
2843 if (instr->hydrogen()->RequiresHoleCheck()) {
2845 DeoptimizeIf(equal, instr, "hole");
2851 void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
2853 Register vector = ToRegister(instr->temp_vector());
2855 __ Move(vector, instr->hydrogen()->feedback_vector());
2859 Smi::FromInt(instr->hydrogen()->slot()));
2863 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
2864 DCHECK(ToRegister(instr->context()).is(rsi));
2865 DCHECK(ToRegister(instr->global_object())
2867 DCHECK(ToRegister(instr->result()).is(rax));
2869 __ Move(LoadDescriptor::NameRegister(), instr->name());
2871 EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
2873 ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
2875 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2879 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
2880 Register value = ToRegister(instr->value());
2881 Handle<Cell> cell_handle = instr->hydrogen()->cell().handle();
2887 if (instr->hydrogen()->RequiresHoleCheck()) {
2889 Register cell = ToRegister(instr->temp());
2893 DeoptimizeIf(equal, instr, "hole");
2905 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
2906 Register context = ToRegister(instr->context());
2907 Register result = ToRegister(instr->result());
2908 __ movp(result, ContextOperand(context, instr->slot_index()));
2909 if (instr->hydrogen()->RequiresHoleCheck()) {
2911 if (instr->hydrogen()->DeoptimizesOnHole()) {
2912 DeoptimizeIf(equal, instr, "hole");
2923 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
2924 Register context = ToRegister(instr->context());
2925 Register value = ToRegister(instr->value());
2927 Operand target = ContextOperand(context, instr->slot_index());
2930 if (instr->hydrogen()->RequiresHoleCheck()) {
2932 if (instr->hydrogen()->DeoptimizesOnHole()) {
2933 DeoptimizeIf(equal, instr, "hole");
2940 if (instr->hydrogen()->NeedsWriteBarrier()) {
2942 instr->hydrogen()->value()->type().IsHeapObject()
2944 int offset = Context::SlotOffset(instr->slot_index());
2945 Register scratch = ToRegister(instr->temp());
2959 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
2960 HObjectAccess access = instr->hydrogen()->access();
2964 Register result = ToRegister(instr->result());
2965 if (instr->object()->IsConstantOperand()) {
2967 __ load_rax(ToExternalReference(LConstantOperand::cast(instr->object())));
2969 Register object = ToRegister(instr->object());
2975 Register object = ToRegister(instr->object());
2976 if (instr->hydrogen()->representation().IsDouble()) {
2977 XMMRegister result = ToDoubleRegister(instr->result());
2982 Register result = ToRegister(instr->result());
2990 instr->hydrogen()->representation().IsInteger32()) {
3007 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
3008 DCHECK(ToRegister(instr->context()).is(rsi));
3009 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister()));
3010 DCHECK(ToRegister(instr->result()).is(rax));
3012 __ Move(LoadDescriptor::NameRegister(), instr->name());
3014 EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
3017 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3021 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
3022 Register function = ToRegister(instr->function());
3023 Register result = ToRegister(instr->result());
3031 DeoptimizeIf(equal, instr, "hole");
3046 void LCodeGen::DoLoadRoot(LLoadRoot* instr) {
3047 Register result = ToRegister(instr->result());
3048 __ LoadRoot(result, instr->index());
3052 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
3053 Register arguments = ToRegister(instr->arguments());
3054 Register result = ToRegister(instr->result());
3056 if (instr->length()->IsConstantOperand() &&
3057 instr->index()->IsConstantOperand()) {
3058 int32_t const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3059 int32_t const_length = ToInteger32(LConstantOperand::cast(instr->length()));
3068 Register length = ToRegister(instr->length());
3071 if (instr->index()->IsRegister()) {
3072 __ subl(length, ToRegister(instr->index()));
3074 __ subl(length, ToOperand(instr->index()));
3083 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
3084 ElementsKind elements_kind = instr->elements_kind();
3085 LOperand* key = instr->key();
3089 instr->hydrogen()->key()->representation();
3092 } else if (instr->hydrogen()->IsDehoisted()) {
3099 instr->elements(),
3101 instr->hydrogen()->key()->representation(),
3103 instr->base_offset()));
3107 XMMRegister result(ToDoubleRegister(instr->result()));
3112 __ movsd(ToDoubleRegister(instr->result()), operand);
3114 Register result(ToRegister(instr->result()));
3141 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
3143 DeoptimizeIf(negative, instr, "negative value");
3165 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
3166 XMMRegister result(ToDoubleRegister(instr->result()));
3167 LOperand* key = instr->key();
3169 instr->hydrogen()->IsDehoisted()) {
3174 if (instr->hydrogen()->RequiresHoleCheck()) {
3176 instr->elements(),
3178 instr->hydrogen()->key()->representation(),
3180 instr->base_offset() + sizeof(kHoleNanLower32));
3182 DeoptimizeIf(equal, instr, "hole");
3186 instr->elements(),
3188 instr->hydrogen()->key()->representation(),
3190 instr->base_offset());
3195 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3196 HLoadKeyed* hinstr = instr->hydrogen();
3197 Register result = ToRegister(instr->result());
3198 LOperand* key = instr->key();
3201 int offset = instr->base_offset();
3204 instr->hydrogen()->IsDehoisted()) {
3215 BuildFastArrayOperand(instr->elements(),
3217 instr->hydrogen()->key()->representation(),
3230 BuildFastArrayOperand(instr->elements(), key,
3231 instr->hydrogen()->key()->representation(),
3239 DeoptimizeIf(NegateCondition(smi), instr, "not a Smi");
3242 DeoptimizeIf(equal, instr, "hole");
3248 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
3249 if (instr->is_typed_elements()) {
3250 DoLoadKeyedExternalArray(instr);
3251 } else if (instr->hydrogen()->representation().IsDouble()) {
3252 DoLoadKeyedFixedDoubleArray(instr);
3254 DoLoadKeyedFixedArray(instr);
3289 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
3290 DCHECK(ToRegister(instr->context()).is(rsi));
3291 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister()));
3292 DCHECK(ToRegister(instr->key()).is(LoadDescriptor::NameRegister()));
3295 EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
3299 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3303 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
3304 Register result = ToRegister(instr->result());
3306 if (instr->hydrogen()->from_inlined()) {
3331 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
3332 Register result = ToRegister(instr->result());
3337 if (instr->elements()->IsRegister()) {
3338 __ cmpp(rbp, ToRegister(instr->elements()));
3340 __ cmpp(rbp, ToOperand(instr->elements()));
3356 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
3357 Register receiver = ToRegister(instr->receiver());
3358 Register function = ToRegister(instr->function());
3366 if (!instr->hydrogen()->known_function()) {
3391 DeoptimizeIf(is_smi, instr, "Smi");
3393 DeoptimizeIf(below, instr, "not a JavaScript object");
3407 void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
3408 Register receiver = ToRegister(instr->receiver());
3409 Register function = ToRegister(instr->function());
3410 Register length = ToRegister(instr->length());
3411 Register elements = ToRegister(instr->elements());
3414 DCHECK(ToRegister(instr->result()).is(rax));
3420 DeoptimizeIf(above, instr, "too many arguments");
3440 DCHECK(instr->HasPointerMap());
3441 LPointerMap* pointers = instr->pointer_map();
3449 void LCodeGen::DoPushArgument(LPushArgument* instr) {
3450 LOperand* argument = instr->value();
3455 void LCodeGen::DoDrop(LDrop* instr) {
3456 __ Drop(instr->count());
3460 void LCodeGen::DoThisFunction(LThisFunction* instr) {
3461 Register result = ToRegister(instr->result());
3466 void LCodeGen::DoContext(LContext* instr) {
3467 Register result = ToRegister(instr->result());
3477 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
3478 DCHECK(ToRegister(instr->context()).is(rsi));
3480 __ Push(instr->hydrogen()->pairs());
3481 __ Push(Smi::FromInt(instr->hydrogen()->flags()));
3482 CallRuntime(Runtime::kDeclareGlobals, 3, instr);
3489 LInstruction* instr,
3496 LPointerMap* pointers = instr->pointer_map();
3520 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0);
3533 LTailCallThroughMegamorphicCache* instr) {
3534 Register receiver = ToRegister(instr->receiver());
3535 Register name = ToRegister(instr->name());
3546 isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(),
3556 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
3557 DCHECK(ToRegister(instr->result()).is(rax));
3559 LPointerMap* pointers = instr->pointer_map();
3562 if (instr->target()->IsConstantOperand()) {
3563 LConstantOperand* target = LConstantOperand::cast(instr->target());
3568 DCHECK(instr->target()->IsRegister());
3569 Register target = ToRegister(instr->target());
3578 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) {
3579 DCHECK(ToRegister(instr->function()).is(rdi));
3580 DCHECK(ToRegister(instr->result()).is(rax));
3582 if (instr->hydrogen()->pass_argument_count()) {
3583 __ Set(rax, instr->arity());
3589 LPointerMap* pointers = instr->pointer_map();
3593 if (instr->hydrogen()->function()->IsConstant()) {
3595 HConstant* fun_const = HConstant::cast(instr->hydrogen()->function());
3611 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3612 Register input_reg = ToRegister(instr->value());
3615 DeoptimizeIf(not_equal, instr, "not a heap number");
3638 Runtime::kAllocateHeapNumber, 0, instr, instr->context());
3655 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
3656 Register input_reg = ToRegister(instr->value());
3661 DeoptimizeIf(negative, instr, "overflow");
3666 void LCodeGen::EmitSmiMathAbs(LMathAbs* instr) {
3667 Register input_reg = ToRegister(instr->value());
3672 DeoptimizeIf(negative, instr, "overflow");
3677 void LCodeGen::DoMathAbs(LMathAbs* instr) {
3681 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr)
3682 : LDeferredCode(codegen), instr_(instr) { }
3686 virtual LInstruction* instr() OVERRIDE { return instr_; }
3691 DCHECK(instr->value()->Equals(instr->result()));
3692 Representation r = instr->hydrogen()->value()->representation();
3696 XMMRegister input_reg = ToDoubleRegister(instr->value());
3701 EmitIntegerMathAbs(instr);
3703 EmitSmiMathAbs(instr);
3706 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
3707 Register input_reg = ToRegister(instr->value());
3710 EmitSmiMathAbs(instr);
3716 void LCodeGen::DoMathFloor(LMathFloor* instr) {
3718 Register output_reg = ToRegister(instr->result());
3719 XMMRegister input_reg = ToDoubleRegister(instr->value());
3723 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3727 DeoptimizeIf(overflow, instr, "minus zero");
3732 DeoptimizeIf(overflow, instr, "overflow");
3738 DeoptimizeIf(parity_even, instr, "NaN");
3741 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3747 DeoptimizeIf(not_zero, instr, "minus zero");
3757 DeoptimizeIf(overflow, instr, "overflow");
3768 DeoptimizeIf(overflow, instr, "overflow");
3775 void LCodeGen::DoMathRound(LMathRound* instr) {
3777 Register output_reg = ToRegister(instr->result());
3778 XMMRegister input_reg = ToDoubleRegister(instr->value());
3779 XMMRegister input_temp = ToDoubleRegister(instr->temp());
3795 DeoptimizeIf(overflow, instr, "overflow");
3811 DeoptimizeIf(overflow, instr, "overflow");
3823 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3826 DeoptimizeIf(negative, instr, "minus zero");
3833 void LCodeGen::DoMathFround(LMathFround* instr) {
3834 XMMRegister input_reg = ToDoubleRegister(instr->value());
3835 XMMRegister output_reg = ToDoubleRegister(instr->result());
3841 void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
3842 XMMRegister output = ToDoubleRegister(instr->result());
3843 if (instr->value()->IsDoubleRegister()) {
3844 XMMRegister input = ToDoubleRegister(instr->value());
3847 Operand input = ToOperand(instr->value());
3853 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
3855 XMMRegister input_reg = ToDoubleRegister(instr->value());
3856 DCHECK(ToDoubleRegister(instr->result()).is(input_reg));
3885 void LCodeGen::DoPower(LPower* instr) {
3886 Representation exponent_type = instr->hydrogen()->right()->representation();
3891 DCHECK(!instr->right()->IsRegister() ||
3892 ToRegister(instr->right()).is(tagged_exponent));
3893 DCHECK(!instr->right()->IsDoubleRegister() ||
3894 ToDoubleRegister(instr->right()).is(xmm1));
3895 DCHECK(ToDoubleRegister(instr->left()).is(xmm2));
3896 DCHECK(ToDoubleRegister(instr->result()).is(xmm3));
3905 DeoptimizeIf(not_equal, instr, "not a heap number");
3920 void LCodeGen::DoMathExp(LMathExp* instr) {
3921 XMMRegister input = ToDoubleRegister(instr->value());
3922 XMMRegister result = ToDoubleRegister(instr->result());
3924 Register temp1 = ToRegister(instr->temp1());
3925 Register temp2 = ToRegister(instr->temp2());
3931 void LCodeGen::DoMathLog(LMathLog* instr) {
3932 DCHECK(instr->value()->Equals(instr->result()));
3933 XMMRegister input_reg = ToDoubleRegister(instr->value());
3964 void LCodeGen::DoMathClz32(LMathClz32* instr) {
3965 Register input = ToRegister(instr->value());
3966 Register result = ToRegister(instr->result());
3978 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
3979 DCHECK(ToRegister(instr->context()).is(rsi));
3980 DCHECK(ToRegister(instr->function()).is(rdi));
3981 DCHECK(instr->HasPointerMap());
3983 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
3985 LPointerMap* pointers = instr->pointer_map();
3987 ParameterCount count(instr->arity());
3991 instr->hydrogen()->formal_parameter_count(),
3992 instr->arity(),
3993 instr,
3999 void LCodeGen::DoCallFunction(LCallFunction* instr) {
4000 DCHECK(ToRegister(instr->context()).is(rsi));
4001 DCHECK(ToRegister(instr->function()).is(rdi));
4002 DCHECK(ToRegister(instr->result()).is(rax));
4004 int arity = instr->arity();
4005 CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
4006 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
4010 void LCodeGen::DoCallNew(LCallNew* instr) {
4011 DCHECK(ToRegister(instr->context()).is(rsi));
4012 DCHECK(ToRegister(instr->constructor()).is(rdi));
4013 DCHECK(ToRegister(instr->result()).is(rax));
4015 __ Set(rax, instr->arity());
4019 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
4023 void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
4024 DCHECK(ToRegister(instr->context()).is(rsi));
4025 DCHECK(ToRegister(instr->constructor()).is(rdi));
4026 DCHECK(ToRegister(instr->result()).is(rax));
4028 __ Set(rax, instr->arity());
4030 ElementsKind kind = instr->hydrogen()->elements_kind();
4036 if (instr->arity() == 0) {
4038 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
4039 } else if (instr->arity() == 1) {
4053 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
4059 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
4063 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
4068 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
4069 DCHECK(ToRegister(instr->context()).is(rsi));
4070 CallRuntime(instr->function(), instr->arity(), instr, instr->save_doubles());
4074 void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) {
4075 Register function = ToRegister(instr->function());
4076 Register code_object = ToRegister(instr->code_object());
4082 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
4083 Register result = ToRegister(instr->result());
4084 Register base = ToRegister(instr->base_object());
4085 if (instr->offset()->IsConstantOperand()) {
4086 LConstantOperand* offset = LConstantOperand::cast(instr->offset());
4089 Register offset = ToRegister(instr->offset());
4095 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
4096 HStoreNamedField* hinstr = instr->hydrogen();
4097 Representation representation = instr->representation();
4104 Register value = ToRegister(instr->value());
4105 if (instr->object()->IsConstantOperand()) {
4107 LConstantOperand* object = LConstantOperand::cast(instr->object());
4110 Register object = ToRegister(instr->object());
4116 Register object = ToRegister(instr->object());
4120 !instr->value()->IsConstantOperand() ||
4121 IsInteger32Constant(LConstantOperand::cast(instr->value())));
4126 XMMRegister value = ToDoubleRegister(instr->value());
4137 Register temp = ToRegister(instr->temp());
4151 write_register = ToRegister(instr->temp());
4172 if (instr->value()->IsRegister()) {
4173 Register value = ToRegister(instr->value());
4176 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4195 Register value = ToRegister(instr->value());
4196 Register temp = access.IsInobject() ? ToRegister(instr->temp()) : object;
4210 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
4211 DCHECK(ToRegister(instr->context()).is(rsi));
4212 DCHECK(ToRegister(instr->object()).is(StoreDescriptor::ReceiverRegister()));
4213 DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister()));
4215 __ Move(StoreDescriptor::NameRegister(), instr->hydrogen()->name());
4216 Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode());
4217 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4221 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
4222 Representation representation = instr->hydrogen()->length()->representation();
4223 DCHECK(representation.Equals(instr->hydrogen()->index()->representation()));
4226 Condition cc = instr->hydrogen()->allow_equality() ? below : below_equal;
4227 if (instr->length()->IsConstantOperand()) {
4228 int32_t length = ToInteger32(LConstantOperand::cast(instr->length()));
4229 Register index = ToRegister(instr->index());
4236 } else if (instr->index()->IsConstantOperand()) {
4237 int32_t index = ToInteger32(LConstantOperand::cast(instr->index()));
4238 if (instr->length()->IsRegister()) {
4239 Register length = ToRegister(instr->length());
4246 Operand length = ToOperand(instr->length());
4254 Register index = ToRegister(instr->index());
4255 if (instr->length()->IsRegister()) {
4256 Register length = ToRegister(instr->length());
4263 Operand length = ToOperand(instr->length());
4271 if (FLAG_debug_code && instr->hydrogen()->skip_check()) {
4277 DeoptimizeIf(cc, instr, "out of bounds");
4282 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4283 ElementsKind elements_kind = instr->elements_kind();
4284 LOperand* key = instr->key();
4288 instr->hydrogen()->key()->representation();
4291 } else if (instr->hydrogen()->IsDehoisted()) {
4298 instr->elements(),
4300 instr->hydrogen()->key()->representation(),
4302 instr->base_offset()));
4306 XMMRegister value(ToDoubleRegister(instr->value()));
4311 __ movsd(operand, ToDoubleRegister(instr->value()));
4313 Register value(ToRegister(instr->value()));
4354 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
4355 XMMRegister value = ToDoubleRegister(instr->value());
4356 LOperand* key = instr->key();
4358 instr->hydrogen()->IsDehoisted()) {
4363 if (instr->NeedsCanonicalization()) {
4378 instr->elements(),
4380 instr->hydrogen()->key()->representation(),
4382 instr->base_offset());
4388 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4389 HStoreKeyed* hinstr = instr->hydrogen();
4390 LOperand* key = instr->key();
4391 int offset = instr->base_offset();
4395 instr->hydrogen()->IsDehoisted()) {
4406 BuildFastArrayOperand(instr->elements(),
4408 instr->hydrogen()->key()->representation(),
4421 BuildFastArrayOperand(instr->elements(),
4423 instr->hydrogen()->key()->representation(),
4426 if (instr->value()->IsRegister()) {
4427 __ Store(operand, ToRegister(instr->value()), representation);
4429 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4445 Register elements = ToRegister(instr->elements());
4446 DCHECK(instr->value()->IsRegister());
4447 Register value = ToRegister(instr->value());
4465 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
4466 if (instr->is_typed_elements()) {
4467 DoStoreKeyedExternalArray(instr);
4468 } else if (instr->hydrogen()->value()->representation().IsDouble()) {
4469 DoStoreKeyedFixedDoubleArray(instr);
4471 DoStoreKeyedFixedArray(instr);
4476 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
4477 DCHECK(ToRegister(instr->context()).is(rsi));
4478 DCHECK(ToRegister(instr->object()).is(StoreDescriptor::ReceiverRegister()));
4479 DCHECK(ToRegister(instr->key()).is(StoreDescriptor::NameRegister()));
4480 DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister()));
4483 CodeFactory::KeyedStoreIC(isolate(), instr->strict_mode()).code();
4484 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4488 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
4489 Register object_reg = ToRegister(instr->object());
4491 Handle<Map> from_map = instr->original_map();
4492 Handle<Map> to_map = instr->transitioned_map();
4493 ElementsKind from_kind = instr->from_kind();
4494 ElementsKind to_kind = instr->to_kind();
4500 Register new_map_reg = ToRegister(instr->new_map_temp());
4504 __ RecordWriteForMap(object_reg, new_map_reg, ToRegister(instr->temp()),
4508 DCHECK(ToRegister(instr->context()).is(rsi));
4514 RecordSafepointWithLazyDeopt(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0);
4520 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
4521 Register object = ToRegister(instr->object());
4522 Register temp = ToRegister(instr->temp());
4525 DeoptimizeIf(equal, instr, "memento found");
4530 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4531 DCHECK(ToRegister(instr->context()).is(rsi));
4532 DCHECK(ToRegister(instr->left()).is(rdx));
4533 DCHECK(ToRegister(instr->right()).is(rax));
4535 instr->hydrogen()->flags(),
4536 instr->hydrogen()->pretenure_flag());
4537 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
4541 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
4544 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
4545 : LDeferredCode(codegen), instr_(instr) { }
4549 virtual LInstruction* instr() OVERRIDE { return instr_; }
4555 new(zone()) DeferredStringCharCodeAt(this, instr);
4558 ToRegister(instr->string()),
4559 ToRegister(instr->index()),
4560 ToRegister(instr->result()),
4566 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
4567 Register string = ToRegister(instr->string());
4568 Register result = ToRegister(instr->result());
4580 if (instr->index()->IsConstantOperand()) {
4581 int32_t const_index = ToInteger32(LConstantOperand::cast(instr->index()));
4584 Register index = ToRegister(instr->index());
4589 Runtime::kStringCharCodeAtRT, 2, instr, instr->context());
4596 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
4599 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
4600 : LDeferredCode(codegen), instr_(instr) { }
4604 virtual LInstruction* instr() OVERRIDE { return instr_; }
4610 new(zone()) DeferredStringCharFromCode(this, instr);
4612 DCHECK(instr->hydrogen()->value()->representation().IsInteger32());
4613 Register char_code = ToRegister(instr->char_code());
4614 Register result = ToRegister(instr->result());
4630 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
4631 Register char_code = ToRegister(instr->char_code());
4632 Register result = ToRegister(instr->result());
4642 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context());
4647 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4648 LOperand* input = instr->value();
4650 LOperand* output = instr->result();
4660 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4661 LOperand* input = instr->value();
4662 LOperand* output = instr->result();
4668 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4671 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
4672 : LDeferredCode(codegen), instr_(instr) { }
4677 virtual LInstruction* instr() OVERRIDE { return instr_; }
4682 LOperand* input = instr->value();
4683 DCHECK(input->IsRegister() && input->Equals(instr->result()));
4690 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr);
4698 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4701 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
4702 : LDeferredCode(codegen), instr_(instr) { }
4707 virtual LInstruction* instr() OVERRIDE { return instr_; }
4712 LOperand* input = instr->value();
4713 DCHECK(input->IsRegister() && input->Equals(instr->result()));
4716 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4724 void LCodeGen::DoDeferredNumberTagIU(LInstruction* instr,
4774 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4785 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
4788 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4789 : LDeferredCode(codegen), instr_(instr) { }
4793 virtual LInstruction* instr() OVERRIDE { return instr_; }
4798 XMMRegister input_reg = ToDoubleRegister(instr->value());
4799 Register reg = ToRegister(instr->result());
4800 Register tmp = ToRegister(instr->temp());
4802 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4813 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
4817 Register reg = ToRegister(instr->result());
4830 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4837 void LCodeGen::DoSmiTag(LSmiTag* instr) {
4838 HChange* hchange = instr->hydrogen();
4839 Register input = ToRegister(instr->value());
4840 Register output = ToRegister(instr->result());
4844 DeoptimizeIf(NegateCondition(is_smi), instr, "overflow");
4849 DeoptimizeIf(overflow, instr, "overflow");
4854 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
4855 DCHECK(instr->value()->Equals(instr->result()));
4856 Register input = ToRegister(instr->value());
4857 if (instr->needs_check()) {
4859 DeoptimizeIf(NegateCondition(is_smi), instr, "not a Smi");
4867 void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg,
4870 instr->hydrogen()->can_convert_undefined_to_nan();
4871 bool deoptimize_on_minus_zero = instr->hydrogen()->deoptimize_on_minus_zero();
4890 DeoptimizeIf(not_equal, instr, "not a heap number");
4900 DeoptimizeIf(not_zero, instr, "minus zero");
4909 DeoptimizeIf(not_equal, instr, "not a heap number/undefined");
4927 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) {
4928 Register input_reg = ToRegister(instr->value());
4930 if (instr->truncating()) {
4956 DeoptimizeIf(not_equal, instr, "not a heap number/undefined/true/false");
4959 XMMRegister scratch = ToDoubleRegister(instr->temp());
4963 DeoptimizeIf(not_equal, instr, "not a heap number");
4968 DeoptimizeIf(not_equal, instr, "lost precision");
4969 DeoptimizeIf(parity_even, instr, "NaN");
4970 if (instr->hydrogen()->GetMinusZeroMode() == FAIL_ON_MINUS_ZERO) {
4975 DeoptimizeIf(not_zero, instr, "minus zero");
4981 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
4984 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
4985 : LDeferredCode(codegen), instr_(instr) { }
4989 virtual LInstruction* instr() OVERRIDE { return instr_; }
4994 LOperand* input = instr->value();
4996 DCHECK(input->Equals(instr->result()));
4999 if (instr->hydrogen()->value()->representation().IsSmi()) {
5002 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
5010 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
5011 LOperand* input = instr->value();
5013 LOperand* result = instr->result();
5019 HValue* value = instr->hydrogen()->value();
5023 EmitNumberUntagD(instr, input_reg, result_reg, mode);
5027 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
5028 LOperand* input = instr->value();
5030 LOperand* result = instr->result();
5036 if (instr->truncating()) {
5043 instr->hydrogen()->GetMinusZeroMode(), &lost_precision,
5047 DeoptimizeIf(no_condition, instr, "lost precision");
5049 DeoptimizeIf(no_condition, instr, "NaN");
5051 DeoptimizeIf(no_condition, instr, "minus zero");
5057 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
5058 LOperand* input = instr->value();
5060 LOperand* result = instr->result();
5070 instr->hydrogen()->GetMinusZeroMode(), &lost_precision, &is_nan,
5074 DeoptimizeIf(no_condition, instr, "lost precision");
5076 DeoptimizeIf(no_condition, instr, "NaN");
5078 DeoptimizeIf(no_condition, instr, "minus zero");
5081 DeoptimizeIf(overflow, instr, "overflow");
5085 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
5086 LOperand* input = instr->value();
5088 DeoptimizeIf(NegateCondition(cc), instr, "not a Smi");
5092 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
5093 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
5094 LOperand* input = instr->value();
5096 DeoptimizeIf(cc, instr, "Smi");
5101 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
5102 Register input = ToRegister(instr->value());
5106 if (instr->hydrogen()->is_interval_check()) {
5109 instr->hydrogen()->GetCheckInterval(&first, &last);
5116 DeoptimizeIf(not_equal, instr, "wrong instance type");
5118 DeoptimizeIf(below, instr, "wrong instance type");
5123 DeoptimizeIf(above, instr, "wrong instance type");
5129 instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
5135 DeoptimizeIf(tag == 0 ? not_zero : zero, instr, "wrong instance type");
5141 DeoptimizeIf(not_equal, instr, "wrong instance type");
5147 void LCodeGen::DoCheckValue(LCheckValue* instr) {
5148 Register reg = ToRegister(instr->value());
5149 __ Cmp(reg, instr->hydrogen()->object().handle());
5150 DeoptimizeIf(not_equal, instr, "value mismatch");
5154 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
5161 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt);
5165 DeoptimizeIf(zero, instr, "instance migration failed");
5169 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
5172 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object)
5173 : LDeferredCode(codegen), instr_(instr), object_(object) {
5180 virtual LInstruction* instr() OVERRIDE { return instr_; }
5187 if (instr->hydrogen()->IsStabilityCheck()) {
5188 const UniqueSet<Map>* maps = instr->hydrogen()->maps();
5195 LOperand* input = instr->value();
5200 if (instr->hydrogen()->HasMigrationTarget()) {
5201 deferred = new(zone()) DeferredCheckMaps(this, instr, reg);
5205 const UniqueSet<Map>* maps = instr->hydrogen()->maps();
5215 if (instr->hydrogen()->HasMigrationTarget()) {
5218 DeoptimizeIf(not_equal, instr, "wrong map");
5225 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
5226 XMMRegister value_reg = ToDoubleRegister(instr->unclamped());
5228 Register result_reg = ToRegister(instr->result());
5233 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
5234 DCHECK(instr->unclamped()->Equals(instr->result()));
5235 Register value_reg = ToRegister(instr->result());
5240 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
5241 DCHECK(instr->unclamped()->Equals(instr->result()));
5242 Register input_reg = ToRegister(instr->unclamped());
5243 XMMRegister temp_xmm_reg = ToDoubleRegister(instr->temp_xmm());
5257 DeoptimizeIf(not_equal, instr, "not a heap number/undefined");
5276 void LCodeGen::DoDoubleBits(LDoubleBits* instr) {
5277 XMMRegister value_reg = ToDoubleRegister(instr->value());
5278 Register result_reg = ToRegister(instr->result());
5279 if (instr->hydrogen()->bits() == HDoubleBits::HIGH) {
5288 void LCodeGen::DoConstructDouble(LConstructDouble* instr) {
5289 Register hi_reg = ToRegister(instr->hi());
5290 Register lo_reg = ToRegister(instr->lo());
5291 XMMRegister result_reg = ToDoubleRegister(instr->result());
5300 void LCodeGen::DoAllocate(LAllocate* instr) {
5303 DeferredAllocate(LCodeGen* codegen, LAllocate* instr)
5304 : LDeferredCode(codegen), instr_(instr) { }
5308 virtual LInstruction* instr() OVERRIDE { return instr_; }
5314 new(zone()) DeferredAllocate(this, instr);
5316 Register result = ToRegister(instr->result());
5317 Register temp = ToRegister(instr->temp());
5321 if (instr->hydrogen()->MustAllocateDoubleAligned()) {
5324 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5325 DCHECK(!instr->hydrogen()->IsOldDataSpaceAllocation());
5326 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
5328 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5329 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
5333 if (instr->size()->IsConstantOperand()) {
5334 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5341 Register size = ToRegister(instr->size());
5347 if (instr->hydrogen()->MustPrefillWithFiller()) {
5348 if (instr->size()->IsConstantOperand()) {
5349 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5352 temp = ToRegister(instr->size());
5366 void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
5367 Register result = ToRegister(instr->result());
5375 if (instr->size()->IsRegister()) {
5376 Register size = ToRegister(instr->size());
5381 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5386 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5387 DCHECK(!instr->hydrogen()->IsOldDataSpaceAllocation());
5388 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
5390 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5391 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
5399 Runtime::kAllocateInTargetSpace, 2, instr, instr->context());
5404 void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
5405 DCHECK(ToRegister(instr->value()).is(rax));
5407 CallRuntime(Runtime::kToFastProperties, 1, instr);
5411 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
5412 DCHECK(ToRegister(instr->context()).is(rsi));
5419 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
5420 __ Move(rcx, instr->hydrogen()->literals());
5428 __ Push(Smi::FromInt(instr->hydrogen()->literal_index()));
5429 __ Push(instr->hydrogen()->pattern());
5430 __ Push(instr->hydrogen()->flags());
5431 CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr);
5443 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr);
5462 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
5463 DCHECK(ToRegister(instr->context()).is(rsi));
5466 bool pretenure = instr->hydrogen()->pretenure();
5467 if (!pretenure && instr->hydrogen()->has_no_literals()) {
5468 FastNewClosureStub stub(isolate(), instr->hydrogen()->strict_mode(),
5469 instr->hydrogen()->kind());
5470 __ Move(rbx, instr->hydrogen()->shared_info());
5471 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
5474 __ Push(instr->hydrogen()->shared_info());
5477 CallRuntime(Runtime::kNewClosure, 3, instr);
5482 void LCodeGen::DoTypeof(LTypeof* instr) {
5483 DCHECK(ToRegister(instr->context()).is(rsi));
5484 LOperand* input = instr->value();
5486 CallRuntime(Runtime::kTypeof, 1, instr);
5502 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
5503 Register input = ToRegister(instr->value());
5504 Condition final_branch_condition = EmitTypeofIs(instr, input);
5506 EmitBranch(instr, final_branch_condition);
5511 Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) {
5512 Label* true_label = instr->TrueLabel(chunk_);
5513 Label* false_label = instr->FalseLabel(chunk_);
5514 Handle<String> type_name = instr->type_literal();
5515 int left_block = instr->TrueDestination(chunk_);
5516 int right_block = instr->FalseDestination(chunk_);
5590 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
5591 Register temp = ToRegister(instr->temp());
5594 EmitBranch(instr, equal);
5630 void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
5632 DCHECK(instr->HasEnvironment());
5633 LEnvironment* env = instr->environment();
5639 void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
5640 Deoptimizer::BailoutType type = instr->hydrogen()->type();
5648 DeoptimizeIf(no_condition, instr, instr->hydrogen()->reason(), type);
5652 void LCodeGen::DoDummy(LDummy* instr) {
5657 void LCodeGen::DoDummyUse(LDummyUse* instr) {
5662 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
5666 RecordSafepointWithLazyDeopt(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0);
5667 DCHECK(instr->HasEnvironment());
5668 LEnvironment* env = instr->environment();
5673 void LCodeGen::DoStackCheck(LStackCheck* instr) {
5676 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
5677 : LDeferredCode(codegen), instr_(instr) { }
5681 virtual LInstruction* instr() OVERRIDE { return instr_; }
5686 DCHECK(instr->HasEnvironment());
5687 LEnvironment* env = instr->environment();
5690 if (instr->hydrogen()->is_function_entry()) {
5696 DCHECK(instr->context()->IsRegister());
5697 DCHECK(ToRegister(instr->context()).is(rsi));
5700 instr);
5703 DCHECK(instr->hydrogen()->is_backwards_branch());
5706 new(zone()) DeferredStackCheck(this, instr);
5710 __ bind(instr->done_label());
5711 deferred_stack_check->SetExit(instr->done_label());
5720 void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
5724 LEnvironment* environment = instr->environment();
5735 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
5736 DCHECK(ToRegister(instr->context()).is(rsi));
5738 DeoptimizeIf(equal, instr, "undefined");
5743 DeoptimizeIf(equal, instr, "null");
5746 DeoptimizeIf(cc, instr, "Smi");
5750 DeoptimizeIf(below_equal, instr, "wrong instance type");
5761 CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr);
5765 DeoptimizeIf(not_equal, instr, "wrong map");
5770 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) {
5771 Register map = ToRegister(instr->map());
5772 Register result = ToRegister(instr->result());
5784 FieldOperand(result, FixedArray::SizeFor(instr->idx())));
5787 DeoptimizeIf(cc, instr, "no cache");
5791 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
5792 Register object = ToRegister(instr->value());
5793 __ cmpp(ToRegister(instr->map()),
5795 DeoptimizeIf(not_equal, instr, "wrong map");
5799 void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
5808 instr->pointer_map(), 2, Safepoint::kNoLazyDeopt);
5813 void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
5817 LLoadFieldByIndex* instr,
5821 instr_(instr),
5828 virtual LInstruction* instr() OVERRIDE { return instr_; }
5835 Register object = ToRegister(instr->object());
5836 Register index = ToRegister(instr->index());
5839 deferred = new(zone()) DeferredLoadMutableDouble(this, instr, object, index);
5870 void LCodeGen::DoStoreFrameContext(LStoreFrameContext* instr) {
5871 Register context = ToRegister(instr->context());
5876 void LCodeGen::DoAllocateBlockContext(LAllocateBlockContext* instr) {
5877 Handle<ScopeInfo> scope_info = instr->scope_info();
5879 __ Push(ToRegister(instr->function()));
5880 CallRuntime(Runtime::kPushBlockContext, 2, instr);