Home | History | Annotate | Download | only in x64

Lines Matching refs:instr

260 void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
261 if (instr->IsCall()) {
264 if (!instr->IsLazyBailout() && !instr->IsGap()) {
270 void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) {
271 if (FLAG_debug_code && FLAG_enable_slow_asserts && instr->HasResult() &&
272 instr->hydrogen_value()->representation().IsInteger32() &&
273 instr->result()->IsRegister()) {
274 __ AssertZeroExtended(ToRegister(instr->result()));
277 if (instr->HasResult() && instr->MustSignExtendResult(chunk())) {
283 if (instr->result()->IsRegister()) {
284 Register result_reg = ToRegister(instr->result());
288 ASSERT(instr->result()->IsStackSlot());
289 Operand src = ToOperand(instr->result());
358 code->instr()->hydrogen_value()->id(),
359 code->instr()->Mnemonic());
626 LInstruction* instr,
629 ASSERT(instr != NULL);
631 RecordSafepointWithLazyDeopt(instr, safepoint_mode, argc);
644 LInstruction* instr) {
645 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT, 0);
651 LInstruction* instr,
653 ASSERT(instr != NULL);
654 ASSERT(instr->HasPointerMap());
658 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0);
682 LInstruction* instr,
688 instr->pointer_map(), argc, Safepoint::kNoLazyDeopt);
881 LInstruction* instr, SafepointMode safepoint_mode, int argc) {
883 RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt);
887 instr->pointer_map(), argc, Safepoint::kLazyDeopt);
975 void LCodeGen::DoInstructionGap(LInstructionGap* instr) {
976 DoGap(instr);
980 void LCodeGen::DoParameter(LParameter* instr) {
985 void LCodeGen::DoCallStub(LCallStub* instr) {
986 ASSERT(ToRegister(instr->context()).is(rsi));
987 ASSERT(ToRegister(instr->result()).is(rax));
988 switch (instr->hydrogen()->major_key()) {
991 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
996 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1001 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1010 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
1015 void LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) {
1016 Register dividend = ToRegister(instr->dividend());
1017 int32_t divisor = instr
1018 ASSERT(dividend.is(ToRegister(instr->result())));
1026 HMod* hmod = instr->hydrogen();
1037 DeoptimizeIf(zero, instr->environment());
1048 void LCodeGen::DoModByConstI(LModByConstI* instr) {
1049 Register dividend = ToRegister(instr->dividend());
1050 int32_t divisor = instr->divisor();
1051 ASSERT(ToRegister(instr->result()).is(rax));
1054 DeoptimizeIf(no_condition, instr->environment());
1064 HMod* hmod = instr->hydrogen();
1069 DeoptimizeIf(less, instr->environment());
1075 void LCodeGen::DoModI(LModI* instr) {
1076 HMod* hmod = instr->hydrogen();
1078 Register left_reg = ToRegister(instr->left());
1080 Register right_reg = ToRegister(instr->right());
1083 Register result_reg = ToRegister(instr->result());
1091 DeoptimizeIf(zero, instr->environment());
1102 DeoptimizeIf(equal, instr->environment());
1122 DeoptimizeIf(zero, instr->environment());
1131 void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
1132 Register dividend = ToRegister(instr->dividend());
1133 int32_t divisor = instr->divisor();
1134 ASSERT(dividend.is(ToRegister(instr->result())));
1147 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1148 DeoptimizeIf(zero, instr->environment());
1153 if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
1154 DeoptimizeIf(overflow, instr->environment());
1160 if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
1175 void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
1176 Register dividend = ToRegister(instr->dividend());
1177 int32_t divisor = instr->divisor();
1178 ASSERT(ToRegister(instr->result()).is(rdx));
1181 DeoptimizeIf(no_condition, instr->environment());
1186 HMathFloorOfDiv* hdiv = instr->hydrogen();
1189 DeoptimizeIf(zero, instr->environment());
1203 Register temp = ToRegister(instr->temp3());
1221 void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) {
1222 HBinaryOperation* hdiv = instr->hydrogen();
1223 Register dividend = ToRegister(instr->dividend());
1224 Register divisor = ToRegister(instr->divisor());
1225 Register remainder = ToRegister(instr->temp());
1226 Register result = ToRegister(instr->result());
1236 DeoptimizeIf(zero, instr->environment());
1245 DeoptimizeIf(sign, instr->environment());
1255 DeoptimizeIf(zero, instr->environment());
1273 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
1274 Register dividend = ToRegister(instr->dividend());
1275 int32_t divisor = instr->divisor();
1276 Register result = ToRegister(instr->result());
1281 HDiv* hdiv = instr->hydrogen();
1284 DeoptimizeIf(zero, instr->environment());
1289 DeoptimizeIf(zero, instr->environment());
1296 DeoptimizeIf(not_zero, instr->environment());
1311 void LCodeGen::DoDivByConstI(LDivByConstI* instr) {
1312 Register dividend = ToRegister(instr->dividend());
1313 int32_t divisor = instr->divisor();
1314 ASSERT(ToRegister(instr->result()).is(rdx));
1317 DeoptimizeIf(no_condition, instr->environment());
1322 HDiv* hdiv = instr->hydrogen();
1325 DeoptimizeIf(zero, instr->environment());
1335 DeoptimizeIf(not_equal, instr->environment());
1341 void LCodeGen::DoDivI(LDivI* instr) {
1342 HBinaryOperation* hdiv = instr->hydrogen();
1343 Register dividend = ToRegister(instr->dividend());
1344 Register divisor = ToRegister(instr->divisor());
1345 Register remainder = ToRegister(instr->temp());
1348 ASSERT(ToRegister(instr->result()).is(rax));
1355 DeoptimizeIf(zero, instr->environment());
1364 DeoptimizeIf(sign, instr->environment());
1374 DeoptimizeIf(zero, instr->environment());
1385 DeoptimizeIf(not_zero, instr->environment());
1390 void LCodeGen::DoMulI(LMulI* instr) {
1391 Register left = ToRegister(instr->left());
1392 LOperand* right = instr->right();
1394 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1395 if (instr->hydrogen_value()->representation().IsSmi()) {
1403 instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1446 if (instr->hydrogen_value()->representation().IsSmi()) {
1453 if (instr->hydrogen_value()->representation().IsSmi()) {
1462 DeoptimizeIf(overflow, instr->environment());
1465 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1468 if (instr->hydrogen_value()->representation().IsSmi()) {
1478 ? !instr->hydrogen_value()->representation().IsSmi()
1481 DeoptimizeIf(no_condition, instr->environment());
1484 DeoptimizeIf(less, instr->environment());
1487 if (instr->hydrogen_value()->representation().IsSmi()) {
1492 DeoptimizeIf(sign, instr->environment());
1495 if (instr->hydrogen_value()->representation().IsSmi()) {
1500 DeoptimizeIf(sign, instr->environment());
1507 void LCodeGen::DoBitI(LBitI* instr) {
1508 LOperand* left = instr->left();
1509 LOperand* right = instr->right();
1510 ASSERT(left->Equals(instr->result()));
1516 instr->hydrogen()->right()->representation());
1517 switch (instr->op()) {
1536 switch (instr->op()) {
1538 if (instr->IsInteger32()) {
1545 if (instr->IsInteger32()) {
1552 if (instr->IsInteger32()) {
1564 switch (instr->op()) {
1566 if (instr->IsInteger32()) {
1573 if (instr->IsInteger32()) {
1580 if (instr->IsInteger32()) {
1594 void LCodeGen::DoShiftI(LShiftI* instr) {
1595 LOperand* left = instr->left();
1596 LOperand* right = instr->right();
1597 ASSERT(left->Equals(instr->result()));
1602 switch (instr->op()) {
1611 if (instr->can_deopt()) {
1613 DeoptimizeIf(negative, instr->environment());
1626 switch (instr->op()) {
1640 } else if (instr->can_deopt()) {
1642 DeoptimizeIf(negative, instr->environment());
1647 if (instr->hydrogen_value()->representation().IsSmi()) {
1652 if (instr->can_deopt()) {
1657 DeoptimizeIf(overflow, instr->environment());
1675 void LCodeGen::DoSubI(LSubI* instr) {
1676 LOperand* left = instr->left();
1677 LOperand* right = instr->right();
1678 ASSERT(left->Equals(instr->result()));
1683 instr->hydrogen()->right()->representation());
1686 if (instr->hydrogen_value()->representation().IsSmi()) {
1692 if (instr->hydrogen_value()->representation().IsSmi()) {
1699 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1700 DeoptimizeIf(overflow, instr->environment());
1705 void LCodeGen::DoConstantI(LConstantI* instr) {
1706 Register dst = ToRegister(instr->result());
1707 if (instr->value() == 0) {
1710 __ movl(dst, Immediate(instr->value()));
1715 void LCodeGen::DoConstantS(LConstantS* instr) {
1716 __ Move(ToRegister(instr->result()), instr->value());
1720 void LCodeGen::DoConstantD(LConstantD* instr) {
1721 ASSERT(instr->result()->IsDoubleRegister());
1722 XMMRegister res = ToDoubleRegister(instr->result());
1723 double v = instr->value();
1730 Register tmp = ToRegister(instr->temp());
1737 void LCodeGen::DoConstantE(LConstantE* instr) {
1738 __ LoadAddress(ToRegister(instr->result()), instr->value());
1742 void LCodeGen::DoConstantT(LConstantT* instr) {
1743 Handle<Object> object = instr->value(isolate());
1745 __ Move(ToRegister(instr->result()), object);
1749 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1750 Register result = ToRegister(instr->result());
1751 Register map = ToRegister(instr->value());
1756 void LCodeGen::DoDateField(LDateField* instr) {
1757 Register object = ToRegister(instr->date());
1758 Register result = ToRegister(instr->result());
1759 Smi* index = instr->index();
1765 DeoptimizeIf(cc, instr->environment());
1767 DeoptimizeIf(not_equal, instr->environment());
1811 void LCodeGen::DoSeqStringGetChar(LSeqStringGetChar* instr) {
1812 String::Encoding encoding = instr->hydrogen()->encoding();
1813 Register result = ToRegister(instr->result());
1814 Register string = ToRegister(instr->string());
1830 Operand operand = BuildSeqStringOperand(string, instr->index(), encoding);
1839 void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
1840 String::Encoding encoding = instr->hydrogen()->encoding();
1841 Register string = ToRegister(instr->string());
1844 Register value = ToRegister(instr->value());
1845 Register index = ToRegister(instr->index());
1849 instr->hydrogen()->encoding() == String::ONE_BYTE_ENCODING
1854 Operand operand = BuildSeqStringOperand(string, instr->index(), encoding);
1855 if (instr->value()->IsConstantOperand()) {
1856 int value = ToInteger32(LConstantOperand::cast(instr->value()));
1866 Register value = ToRegister(instr->value());
1876 void LCodeGen::DoAddI(LAddI* instr) {
1877 LOperand* left = instr->left();
1878 LOperand* right = instr->right();
1880 Representation target_rep = instr->hydrogen()->representation();
1883 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) {
1889 instr->hydrogen()->right()->representation());
1891 __ leap(ToRegister(instr->result()),
1894 __ leal(ToRegister(instr->result()),
1900 __ leap(ToRegister(instr->result()), address);
1902 __ leal(ToRegister(instr->result()), address);
1911 instr->hydrogen()->right()->representation());
1930 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1931 DeoptimizeIf(overflow, instr->environment());
1937 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
1938 LOperand* left = instr->left();
1939 LOperand* right = instr->right();
1940 ASSERT(left->Equals(instr->result()));
1941 HMathMinMax::Operation operation = instr->hydrogen()->operation();
1942 if (instr->hydrogen()->representation().IsSmiOrInteger32()) {
1951 instr->hydrogen()->right()->representation()));
1953 ? !instr->hydrogen()->representation().IsSmi()
1960 if (instr->hydrogen_value()->representation().IsSmi()) {
1969 if (instr->hydrogen_value()->representation().IsSmi()) {
1979 ASSERT(instr->hydrogen()->representation().IsDouble());
2015 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
2016 XMMRegister left = ToDoubleRegister(instr->left());
2017 XMMRegister right = ToDoubleRegister(instr->right());
2018 XMMRegister result = ToDoubleRegister(instr->result());
2020 ASSERT(instr
2021 switch (instr->op()) {
2054 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
2055 ASSERT(ToRegister(instr->context()).is(rsi));
2056 ASSERT(ToRegister(instr->left()).is(rdx));
2057 ASSERT(ToRegister(instr->right()).is(rax));
2058 ASSERT(ToRegister(instr->result()).is(rax));
2060 BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE);
2061 CallCode(stub.GetCode(), 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->environment());
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->environment());
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 ASSERT(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 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 ASSERT(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() V8_OVERRIDE { return instr_; }
2689 ASSERT(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 ASSERT(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->environment());
2850 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
2851 ASSERT(ToRegister(instr->context()).is(rsi));
2852 ASSERT(ToRegister(instr->global_object()).is(rax));
2853 ASSERT(ToRegister(instr->result()).is(rax));
2855 __ Move(rcx, instr->name());
2856 ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
2858 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2862 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
2863 Register value = ToRegister(instr->value());
2864 Handle<Cell> cell_handle = instr->hydrogen()->cell().handle();
2870 if (instr->hydrogen()->RequiresHoleCheck()) {
2872 Register cell = ToRegister(instr->temp());
2876 DeoptimizeIf(equal, instr->environment());
2888 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
2889 Register context = ToRegister(instr->context());
2890 Register result = ToRegister(instr->result());
2891 __ movp(result, ContextOperand(context, instr->slot_index()));
2892 if (instr->hydrogen()->RequiresHoleCheck()) {
2894 if (instr->hydrogen()->DeoptimizesOnHole()) {
2895 DeoptimizeIf(equal, instr->environment());
2906 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
2907 Register context = ToRegister(instr->context());
2908 Register value = ToRegister(instr->value());
2910 Operand target = ContextOperand(context, instr->slot_index());
2913 if (instr->hydrogen()->RequiresHoleCheck()) {
2915 if (instr->hydrogen()->DeoptimizesOnHole()) {
2916 DeoptimizeIf(equal, instr->environment());
2923 if (instr->hydrogen()->NeedsWriteBarrier()) {
2925 instr->hydrogen()->value()->type().IsHeapObject()
2927 int offset = Context::SlotOffset(instr->slot_index());
2928 Register scratch = ToRegister(instr->temp());
2942 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
2943 HObjectAccess access = instr->hydrogen()->access();
2947 Register result = ToRegister(instr->result());
2948 if (instr->object()->IsConstantOperand()) {
2950 __ load_rax(ToExternalReference(LConstantOperand::cast(instr->object())));
2952 Register object = ToRegister(instr->object());
2958 Register object = ToRegister(instr->object());
2959 if (instr->hydrogen()->representation().IsDouble()) {
2960 XMMRegister result = ToDoubleRegister(instr->result());
2965 Register result = ToRegister(instr->result());
2973 instr->hydrogen()->representation().IsInteger32()) {
2990 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
2991 ASSERT(ToRegister(instr->context()).is(rsi));
2992 ASSERT(ToRegister(instr->object()).is(rax));
2993 ASSERT(ToRegister(instr->result()).is(rax));
2995 __ Move(rcx, instr->name());
2997 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3001 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
3002 Register function = ToRegister(instr->function());
3003 Register result = ToRegister(instr->result());
3007 DeoptimizeIf(not_equal, instr->environment());
3021 DeoptimizeIf(equal, instr->environment());
3042 void LCodeGen::DoLoadRoot(LLoadRoot* instr) {
3043 Register result = ToRegister(instr->result());
3044 __ LoadRoot(result, instr->index());
3048 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
3049 Register arguments = ToRegister(instr->arguments());
3050 Register result = ToRegister(instr->result());
3052 if (instr->length()->IsConstantOperand() &&
3053 instr->index()->IsConstantOperand()) {
3054 int32_t const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3055 int32_t const_length = ToInteger32(LConstantOperand::cast(instr->length()));
3064 Register length = ToRegister(instr->length());
3067 if (instr->index()->IsRegister()) {
3068 __ subl(length, ToRegister(instr->index()));
3070 __ subl(length, ToOperand(instr->index()));
3079 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
3080 ElementsKind elements_kind = instr->elements_kind();
3081 LOperand* key = instr->key();
3085 instr->hydrogen()->key()->representation();
3088 } else if (instr->hydrogen()->IsDehoisted()) {
3095 instr->elements(),
3097 instr->hydrogen()->key()->representation(),
3099 instr->base_offset()));
3103 XMMRegister result(ToDoubleRegister(instr->result()));
3108 __ movsd(ToDoubleRegister(instr->result()), operand);
3110 Register result(ToRegister(instr->result()));
3137 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
3139 DeoptimizeIf(negative, instr->environment());
3161 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
3162 XMMRegister result(ToDoubleRegister(instr->result()));
3163 LOperand* key = instr->key();
3165 instr->hydrogen()->IsDehoisted()) {
3170 if (instr->hydrogen()->RequiresHoleCheck()) {
3172 instr->elements(),
3174 instr->hydrogen()->key()->representation(),
3176 instr->base_offset() + sizeof(kHoleNanLower32));
3178 DeoptimizeIf(equal, instr->environment());
3182 instr->elements(),
3184 instr->hydrogen()->key()->representation(),
3186 instr->base_offset());
3191 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3192 HLoadKeyed* hinstr = instr->hydrogen();
3193 Register result = ToRegister(instr->result());
3194 LOperand* key = instr->key();
3197 int offset = instr->base_offset();
3200 instr->hydrogen()->IsDehoisted()) {
3211 BuildFastArrayOperand(instr->elements(),
3213 instr->hydrogen()->key()->representation(),
3226 BuildFastArrayOperand(instr->elements(),
3228 instr->hydrogen()->key()->representation(),
3237 DeoptimizeIf(NegateCondition(smi), instr->environment());
3240 DeoptimizeIf(equal, instr->environment());
3246 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
3247 if (instr->is_typed_elements()) {
3248 DoLoadKeyedExternalArray(instr);
3249 } else if (instr->hydrogen()->representation().IsDouble()) {
3250 DoLoadKeyedFixedDoubleArray(instr);
3252 DoLoadKeyedFixedArray(instr);
3287 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
3288 ASSERT(ToRegister(instr->context()).is(rsi));
3289 ASSERT(ToRegister(instr->object()).is(rdx));
3290 ASSERT(ToRegister(instr->key()).is(rax));
3293 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3297 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
3298 Register result = ToRegister(instr->result());
3300 if (instr->hydrogen()->from_inlined()) {
3325 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
3326 Register result = ToRegister(instr->result());
3331 if (instr->elements()->IsRegister()) {
3332 __ cmpp(rbp, ToRegister(instr->elements()));
3334 __ cmpp(rbp, ToOperand(instr->elements()));
3350 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
3351 Register receiver = ToRegister(instr->receiver());
3352 Register function = ToRegister(instr->function());
3360 if (!instr->hydrogen()->known_function()) {
3385 DeoptimizeIf(is_smi, instr->environment());
3387 DeoptimizeIf(below, instr->environment());
3402 void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
3403 Register receiver = ToRegister(instr->receiver());
3404 Register function = ToRegister(instr->function());
3405 Register length = ToRegister(instr->length());
3406 Register elements = ToRegister(instr->elements());
3409 ASSERT(ToRegister(instr->result()).is(rax));
3415 DeoptimizeIf(above, instr->environment());
3435 ASSERT(instr->HasPointerMap());
3436 LPointerMap* pointers = instr->pointer_map();
3444 void LCodeGen::DoPushArgument(LPushArgument* instr) {
3445 LOperand* argument = instr->value();
3450 void LCodeGen::DoDrop(LDrop* instr) {
3451 __ Drop(instr->count());
3455 void LCodeGen::DoThisFunction(LThisFunction* instr) {
3456 Register result = ToRegister(instr->result());
3461 void LCodeGen::DoContext(LContext* instr) {
3462 Register result = ToRegister(instr->result());
3472 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
3473 ASSERT(ToRegister(instr->context()).is(rsi));
3475 __ Push(instr->hydrogen()->pairs());
3476 __ Push(Smi::FromInt(instr->hydrogen()->flags()));
3477 CallRuntime(Runtime::kHiddenDeclareGlobals, 3, instr);
3484 LInstruction* instr,
3491 LPointerMap* pointers = instr->pointer_map();
3515 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0);
3527 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
3528 ASSERT(ToRegister(instr->result()).is(rax));
3530 LPointerMap* pointers = instr->pointer_map();
3533 if (instr->target()->IsConstantOperand()) {
3534 LConstantOperand* target = LConstantOperand::cast(instr->target());
3539 ASSERT(instr->target()->IsRegister());
3540 Register target = ToRegister(instr->target());
3549 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) {
3550 ASSERT(ToRegister(instr->function()).is(rdi));
3551 ASSERT(ToRegister(instr->result()).is(rax));
3553 if (instr->hydrogen()->pass_argument_count()) {
3554 __ Set(rax, instr->arity());
3560 LPointerMap* pointers = instr->pointer_map();
3564 if (instr->hydrogen()->function()->IsConstant()) {
3566 HConstant* fun_const = HConstant::cast(instr->hydrogen()->function());
3582 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3583 Register input_reg = ToRegister(instr->value());
3586 DeoptimizeIf(not_equal, instr->environment());
3609 Runtime::kHiddenAllocateHeapNumber, 0, instr, instr->context());
3626 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
3627 Register input_reg = ToRegister(instr->value());
3632 DeoptimizeIf(negative, instr->environment());
3637 void LCodeGen::EmitSmiMathAbs(LMathAbs* instr) {
3638 Register input_reg = ToRegister(instr->value());
3643 DeoptimizeIf(negative, instr->environment());
3648 void LCodeGen::DoMathAbs(LMathAbs* instr) {
3652 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr)
3653 : LDeferredCode(codegen), instr_(instr) { }
3657 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
3662 ASSERT(instr->value()->Equals(instr->result()));
3663 Representation r = instr->hydrogen()->value()->representation();
3667 XMMRegister input_reg = ToDoubleRegister(instr->value());
3672 EmitIntegerMathAbs(instr);
3674 EmitSmiMathAbs(instr);
3677 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
3678 Register input_reg = ToRegister(instr->value());
3681 EmitSmiMathAbs(instr);
3687 void LCodeGen::DoMathFloor(LMathFloor* instr) {
3689 Register output_reg = ToRegister(instr->result());
3690 XMMRegister input_reg = ToDoubleRegister(instr->value());
3694 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3698 DeoptimizeIf(overflow, instr->environment());
3703 DeoptimizeIf(overflow, instr->environment());
3709 DeoptimizeIf(parity_even, instr->environment());
3712 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3718 DeoptimizeIf(not_zero, instr->environment());
3728 DeoptimizeIf(overflow, instr->environment());
3739 DeoptimizeIf(overflow, instr->environment());
3746 void LCodeGen::DoMathRound(LMathRound* instr) {
3748 Register output_reg = ToRegister(instr->result());
3749 XMMRegister input_reg = ToDoubleRegister(instr->value());
3750 XMMRegister input_temp = ToDoubleRegister(instr->temp());
3767 DeoptimizeIf(overflow, instr->environment());
3784 DeoptimizeIf(overflow, instr->environment());
3796 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3800 DeoptimizeIf(negative, instr->environment());
3807 void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
3808 XMMRegister output = ToDoubleRegister(instr->result());
3809 if (instr->value()->IsDoubleRegister()) {
3810 XMMRegister input = ToDoubleRegister(instr->value());
3813 Operand input = ToOperand(instr->value());
3819 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
3821 XMMRegister input_reg = ToDoubleRegister(instr->value());
3822 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
3851 void LCodeGen::DoPower(LPower* instr) {
3852 Representation exponent_type = instr->hydrogen()->right()->representation();
3857 ASSERT(!instr->right()->IsRegister() ||
3858 ToRegister(instr->right()).is(exponent));
3859 ASSERT(!instr->right()->IsDoubleRegister() ||
3860 ToDoubleRegister(instr->right()).is(xmm1));
3861 ASSERT(ToDoubleRegister(instr->left()).is(xmm2));
3862 ASSERT(ToDoubleRegister(instr->result()).is(xmm3));
3871 DeoptimizeIf(not_equal, instr->environment());
3886 void LCodeGen::DoMathExp(LMathExp* instr) {
3887 XMMRegister input = ToDoubleRegister(instr->value());
3888 XMMRegister result = ToDoubleRegister(instr->result());
3890 Register temp1 = ToRegister(instr->temp1());
3891 Register temp2 = ToRegister(instr->temp2());
3897 void LCodeGen::DoMathLog(LMathLog* instr) {
3898 ASSERT(instr->value()->Equals(instr->result()));
3899 XMMRegister input_reg = ToDoubleRegister(instr->value());
3930 void LCodeGen::DoMathClz32(LMathClz32* instr) {
3931 Register input = ToRegister(instr->value());
3932 Register result = ToRegister(instr->result());
3944 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
3945 ASSERT(ToRegister(instr->context()).is(rsi));
3946 ASSERT(ToRegister(instr->function()).is(rdi));
3947 ASSERT(instr->HasPointerMap());
3949 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
3951 LPointerMap* pointers = instr->pointer_map();
3953 ParameterCount count(instr->arity());
3957 instr->hydrogen()->formal_parameter_count(),
3958 instr->arity(),
3959 instr,
3965 void LCodeGen::DoCallFunction(LCallFunction* instr) {
3966 ASSERT(ToRegister(instr->context()).is(rsi));
3967 ASSERT(ToRegister(instr->function()).is(rdi));
3968 ASSERT(ToRegister(instr->result()).is(rax));
3970 int arity = instr->arity();
3971 CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
3972 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
3976 void LCodeGen::DoCallNew(LCallNew* instr) {
3977 ASSERT(ToRegister(instr->context()).is(rsi));
3978 ASSERT(ToRegister(instr->constructor()).is(rdi));
3979 ASSERT(ToRegister(instr->result()).is(rax));
3981 __ Set(rax, instr->arity());
3985 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
3989 void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
3990 ASSERT(ToRegister(instr->context()).is(rsi));
3991 ASSERT(ToRegister(instr->constructor()).is(rdi));
3992 ASSERT(ToRegister(instr->result()).is(rax));
3994 __ Set(rax, instr->arity());
3996 ElementsKind kind = instr->hydrogen()->elements_kind();
4002 if (instr->arity() == 0) {
4004 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
4005 } else if (instr->arity() == 1) {
4019 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
4025 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
4029 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
4034 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
4035 ASSERT(ToRegister(instr->context()).is(rsi));
4036 CallRuntime(instr->function(), instr->arity(), instr, instr->save_doubles());
4040 void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) {
4041 Register function = ToRegister(instr->function());
4042 Register code_object = ToRegister(instr->code_object());
4048 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
4049 Register result = ToRegister(instr->result());
4050 Register base = ToRegister(instr->base_object());
4051 if (instr->offset()->IsConstantOperand()) {
4052 LConstantOperand* offset = LConstantOperand::cast(instr->offset());
4055 Register offset = ToRegister(instr->offset());
4061 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
4062 HStoreNamedField* hinstr = instr->hydrogen();
4063 Representation representation = instr->representation();
4070 Register value = ToRegister(instr->value());
4071 if (instr->object()->IsConstantOperand()) {
4073 LConstantOperand* object = LConstantOperand::cast(instr->object());
4076 Register object = ToRegister(instr->object());
4082 Register object = ToRegister(instr->object());
4086 !instr->value()->IsConstantOperand() ||
4087 IsInteger32Constant(LConstantOperand::cast(instr->value())));
4092 XMMRegister value = ToDoubleRegister(instr->value());
4103 Register temp = ToRegister(instr->temp());
4117 write_register = ToRegister(instr->temp());
4138 if (instr->value()->IsRegister()) {
4139 Register value = ToRegister(instr->value());
4142 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4161 Register value = ToRegister(instr->value());
4162 Register temp = access.IsInobject() ? ToRegister(instr->temp()) : object;
4176 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
4177 ASSERT(ToRegister(instr->context()).is(rsi));
4178 ASSERT(ToRegister(instr->object()).is(rdx));
4179 ASSERT(ToRegister(instr->value()).is(rax));
4181 __ Move(rcx, instr->hydrogen()->name());
4182 Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode());
4183 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4187 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
4188 Representation representation = instr->hydrogen()->length()->representation();
4189 ASSERT(representation.Equals(instr->hydrogen()->index()->representation()));
4192 Condition cc = instr->hydrogen()->allow_equality() ? below : below_equal;
4193 if (instr->length()->IsConstantOperand()) {
4194 int32_t length = ToInteger32(LConstantOperand::cast(instr->length()));
4195 Register index = ToRegister(instr->index());
4202 } else if (instr->index()->IsConstantOperand()) {
4203 int32_t index = ToInteger32(LConstantOperand::cast(instr->index()));
4204 if (instr->length()->IsRegister()) {
4205 Register length = ToRegister(instr->length());
4212 Operand length = ToOperand(instr->length());
4220 Register index = ToRegister(instr->index());
4221 if (instr->length()->IsRegister()) {
4222 Register length = ToRegister(instr->length());
4229 Operand length = ToOperand(instr->length());
4237 if (FLAG_debug_code && instr->hydrogen()->skip_check()) {
4243 DeoptimizeIf(cc, instr->environment());
4248 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4249 ElementsKind elements_kind = instr->elements_kind();
4250 LOperand* key = instr->key();
4254 instr->hydrogen()->key()->representation();
4257 } else if (instr->hydrogen()->IsDehoisted()) {
4264 instr->elements(),
4266 instr->hydrogen()->key()->representation(),
4268 instr->base_offset()));
4272 XMMRegister value(ToDoubleRegister(instr->value()));
4277 __ movsd(operand, ToDoubleRegister(instr->value()));
4279 Register value(ToRegister(instr->value()));
4320 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
4321 XMMRegister value = ToDoubleRegister(instr->value());
4322 LOperand* key = instr->key();
4324 instr->hydrogen()->IsDehoisted()) {
4329 if (instr->NeedsCanonicalization()) {
4343 instr->elements(),
4345 instr->hydrogen()->key()->representation(),
4347 instr->base_offset());
4353 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4354 HStoreKeyed* hinstr = instr->hydrogen();
4355 LOperand* key = instr->key();
4356 int offset = instr->base_offset();
4360 instr->hydrogen()->IsDehoisted()) {
4371 BuildFastArrayOperand(instr->elements(),
4373 instr->hydrogen()->key()->representation(),
4386 BuildFastArrayOperand(instr->elements(),
4388 instr->hydrogen()->key()->representation(),
4391 if (instr
4392 __ Store(operand, ToRegister(instr->value()), representation);
4394 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4410 Register elements = ToRegister(instr->elements());
4411 ASSERT(instr->value()->IsRegister());
4412 Register value = ToRegister(instr->value());
4430 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
4431 if (instr->is_typed_elements()) {
4432 DoStoreKeyedExternalArray(instr);
4433 } else if (instr->hydrogen()->value()->representation().IsDouble()) {
4434 DoStoreKeyedFixedDoubleArray(instr);
4436 DoStoreKeyedFixedArray(instr);
4441 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
4442 ASSERT(ToRegister(instr->context()).is(rsi));
4443 ASSERT(ToRegister(instr->object()).is(rdx));
4444 ASSERT(ToRegister(instr->key()).is(rcx));
4445 ASSERT(ToRegister(instr->value()).is(rax));
4447 Handle<Code> ic = instr->strict_mode() == STRICT
4450 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4454 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
4455 Register object_reg = ToRegister(instr->object());
4457 Handle<Map> from_map = instr->original_map();
4458 Handle<Map> to_map = instr->transitioned_map();
4459 ElementsKind from_kind = instr->from_kind();
4460 ElementsKind to_kind = instr->to_kind();
4466 Register new_map_reg = ToRegister(instr->new_map_temp());
4470 __ RecordWriteForMap(object_reg, new_map_reg, ToRegister(instr->temp()),
4474 ASSERT(ToRegister(instr->context()).is(rsi));
4480 RecordSafepointWithLazyDeopt(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0);
4486 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
4487 Register object = ToRegister(instr->object());
4488 Register temp = ToRegister(instr->temp());
4491 DeoptimizeIf(equal, instr->environment());
4496 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4497 ASSERT(ToRegister(instr->context()).is(rsi));
4498 ASSERT(ToRegister(instr->left()).is(rdx));
4499 ASSERT(ToRegister(instr->right()).is(rax));
4501 instr->hydrogen()->flags(),
4502 instr->hydrogen()->pretenure_flag());
4503 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
4507 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
4510 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
4511 : LDeferredCode(codegen), instr_(instr) { }
4515 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4521 new(zone()) DeferredStringCharCodeAt(this, instr);
4524 ToRegister(instr->string()),
4525 ToRegister(instr->index()),
4526 ToRegister(instr->result()),
4532 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
4533 Register string = ToRegister(instr->string());
4534 Register result = ToRegister(instr->result());
4546 if (instr->index()->IsConstantOperand()) {
4547 int32_t const_index = ToInteger32(LConstantOperand::cast(instr->index()));
4550 Register index = ToRegister(instr->index());
4555 Runtime::kHiddenStringCharCodeAt, 2, instr, instr->context());
4562 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
4565 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
4566 : LDeferredCode(codegen), instr_(instr) { }
4570 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4576 new(zone()) DeferredStringCharFromCode(this, instr);
4578 ASSERT(instr->hydrogen()->value()->representation().IsInteger32());
4579 Register char_code = ToRegister(instr->char_code());
4580 Register result = ToRegister(instr->result());
4596 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
4597 Register char_code = ToRegister(instr->char_code());
4598 Register result = ToRegister(instr->result());
4608 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context());
4613 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4614 LOperand* input = instr->value();
4616 LOperand* output = instr->result();
4626 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4627 LOperand* input = instr->value();
4628 LOperand* output = instr->result();
4634 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4637 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
4638 : LDeferredCode(codegen), instr_(instr) { }
4643 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4648 LOperand* input = instr->value();
4649 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4656 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr);
4664 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4667 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
4668 : LDeferredCode(codegen), instr_(instr) { }
4673 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4678 LOperand* input = instr->value();
4679 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4682 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4690 void LCodeGen::DoDeferredNumberTagIU(LInstruction* instr,
4740 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4751 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
4754 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4755 : LDeferredCode(codegen), instr_(instr) { }
4759 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4764 XMMRegister input_reg = ToDoubleRegister(instr->value());
4765 Register reg = ToRegister(instr->result());
4766 Register tmp = ToRegister(instr->temp());
4768 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4779 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
4783 Register reg = ToRegister(instr->result());
4796 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4803 void LCodeGen::DoSmiTag(LSmiTag* instr) {
4804 HChange* hchange = instr->hydrogen();
4805 Register input = ToRegister(instr->value());
4806 Register output = ToRegister(instr->result());
4810 DeoptimizeIf(NegateCondition(is_smi), instr->environment());
4815 DeoptimizeIf(overflow, instr->environment());
4820 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
4821 ASSERT(instr->value()->Equals(instr->result()));
4822 Register input = ToRegister(instr->value());
4823 if (instr->needs_check()) {
4825 DeoptimizeIf(NegateCondition(is_smi), instr->environment());
4893 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) {
4894 Register input_reg = ToRegister(instr->value());
4896 if (instr->truncating()) {
4923 DeoptimizeIf(not_equal, instr->environment());
4928 XMMRegister xmm_temp = ToDoubleRegister(instr->temp());
4930 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);
4934 DeoptimizeIf(no_condition, instr->environment());
4939 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
4942 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
4943 : LDeferredCode(codegen), instr_(instr) { }
4947 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4952 LOperand* input = instr->value();
4954 ASSERT(input->Equals(instr->result()));
4957 if (instr->hydrogen()->value()->representation().IsSmi()) {
4960 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
4968 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
4969 LOperand* input = instr->value();
4971 LOperand* result = instr->result();
4977 HValue* value = instr->hydrogen()->value();
4982 instr->hydrogen()->can_convert_undefined_to_nan(),
4983 instr->hydrogen()->deoptimize_on_minus_zero(),
4984 instr->environment(),
4989 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
4990 LOperand* input = instr->value();
4992 LOperand* result = instr->result();
4998 if (instr->truncating()) {
5004 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);
5008 DeoptimizeIf(no_condition, instr->environment());
5014 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
5015 LOperand* input = instr->value();
5017 LOperand* result = instr->result();
5026 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);
5030 DeoptimizeIf(no_condition, instr->environment());
5034 DeoptimizeIf(overflow, instr->environment());
5038 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
5039 LOperand* input = instr->value();
5041 DeoptimizeIf(NegateCondition(cc), instr->environment());
5045 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
5046 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
5047 LOperand* input = instr->value();
5049 DeoptimizeIf(cc, instr->environment());
5054 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
5055 Register input = ToRegister(instr->value());
5059 if (instr->hydrogen()->is_interval_check()) {
5062 instr->hydrogen()->GetCheckInterval(&first, &last);
5069 DeoptimizeIf(not_equal, instr->environment());
5071 DeoptimizeIf(below, instr->environment());
5076 DeoptimizeIf(above, instr->environment());
5082 instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
5088 DeoptimizeIf(tag == 0 ? not_zero : zero, instr->environment());
5094 DeoptimizeIf(not_equal, instr->environment());
5100 void LCodeGen::DoCheckValue(LCheckValue* instr) {
5101 Register reg = ToRegister(instr->value());
5102 __ Cmp(reg, instr->hydrogen()->object().handle());
5103 DeoptimizeIf(not_equal, instr->environment());
5107 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
5114 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt);
5118 DeoptimizeIf(zero, instr->environment());
5122 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
5125 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object)
5126 : LDeferredCode(codegen), instr_(instr), object_(object) {
5133 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5140 if (instr->hydrogen()->IsStabilityCheck()) {
5141 const UniqueSet<Map>* maps = instr->hydrogen()->maps();
5148 LOperand* input = instr->value();
5153 if (instr->hydrogen()->HasMigrationTarget()) {
5154 deferred = new(zone()) DeferredCheckMaps(this, instr, reg);
5158 const UniqueSet<Map>* maps = instr->hydrogen()->maps();
5168 if (instr->hydrogen()->HasMigrationTarget()) {
5171 DeoptimizeIf(not_equal, instr->environment());
5178 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
5179 XMMRegister value_reg = ToDoubleRegister(instr->unclamped());
5181 Register result_reg = ToRegister(instr->result());
5186 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
5187 ASSERT(instr->unclamped()->Equals(instr->result()));
5188 Register value_reg = ToRegister(instr->result());
5193 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
5194 ASSERT(instr->unclamped()->Equals(instr->result()));
5195 Register input_reg = ToRegister(instr->unclamped());
5196 XMMRegister temp_xmm_reg = ToDoubleRegister(instr->temp_xmm());
5210 DeoptimizeIf(not_equal, instr->environment());
5229 void LCodeGen::DoDoubleBits(LDoubleBits* instr) {
5230 XMMRegister value_reg = ToDoubleRegister(instr->value());
5231 Register result_reg = ToRegister(instr->result());
5232 if (instr->hydrogen()->bits() == HDoubleBits::HIGH) {
5241 void LCodeGen::DoConstructDouble(LConstructDouble* instr) {
5242 Register hi_reg = ToRegister(instr->hi());
5243 Register lo_reg = ToRegister(instr->lo());
5244 XMMRegister result_reg = ToDoubleRegister(instr->result());
5253 void LCodeGen::DoAllocate(LAllocate* instr) {
5256 DeferredAllocate(LCodeGen* codegen, LAllocate* instr)
5257 : LDeferredCode(codegen), instr_(instr) { }
5261 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5267 new(zone()) DeferredAllocate(this, instr);
5269 Register result = ToRegister(instr->result());
5270 Register temp = ToRegister(instr->temp());
5274 if (instr->hydrogen()->MustAllocateDoubleAligned()) {
5277 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5278 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation());
5279 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5281 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5282 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5286 if (instr->size()->IsConstantOperand()) {
5287 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5294 Register size = ToRegister(instr->size());
5300 if (instr->hydrogen()->MustPrefillWithFiller()) {
5301 if (instr->size()->IsConstantOperand()) {
5302 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5305 temp = ToRegister(instr->size());
5319 void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
5320 Register result = ToRegister(instr->result());
5328 if (instr->size()->IsRegister()) {
5329 Register size = ToRegister(instr->size());
5334 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5339 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5340 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation());
5341 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5343 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5344 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5352 Runtime::kHiddenAllocateInTargetSpace, 2, instr, instr->context());
5357 void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
5358 ASSERT(ToRegister(instr->value()).is(rax));
5360 CallRuntime(Runtime::kToFastProperties, 1, instr);
5364 instr) {
5365 ASSERT(ToRegister(instr->context()).is(rsi));
5372 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
5373 __ Move(rcx, instr->hydrogen()->literals());
5381 __ Push(Smi::FromInt(instr->hydrogen()->literal_index()));
5382 __ Push(instr->hydrogen()->pattern());
5383 __ Push(instr->hydrogen()->flags());
5384 CallRuntime(Runtime::kHiddenMaterializeRegExpLiteral, 4, instr);
5396 CallRuntime(Runtime::kHiddenAllocateInNewSpace, 1, instr);
5415 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
5416 ASSERT(ToRegister(instr->context()).is(rsi));
5419 bool pretenure = instr->hydrogen()->pretenure();
5420 if (!pretenure && instr->hydrogen()->has_no_literals()) {
5422 instr->hydrogen()->strict_mode(),
5423 instr->hydrogen()->is_generator());
5424 __ Move(rbx, instr->hydrogen()->shared_info());
5425 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
5428 __ Push(instr->hydrogen()->shared_info());
5431 CallRuntime(Runtime::kHiddenNewClosure, 3, instr);
5436 void LCodeGen::DoTypeof(LTypeof* instr) {
5437 ASSERT(ToRegister(instr->context()).is(rsi));
5438 LOperand* input = instr->value();
5440 CallRuntime(Runtime::kTypeof, 1, instr);
5456 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
5457 Register input = ToRegister(instr->value());
5458 Condition final_branch_condition = EmitTypeofIs(instr, input);
5460 EmitBranch(instr, final_branch_condition);
5465 Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) {
5466 Label* true_label = instr->TrueLabel(chunk_);
5467 Label* false_label = instr->FalseLabel(chunk_);
5468 Handle<String> type_name = instr->type_literal();
5469 int left_block = instr->TrueDestination(chunk_);
5470 int right_block = instr->FalseDestination(chunk_);
5551 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
5552 Register temp = ToRegister(instr->temp());
5555 EmitBranch(instr, equal);
5591 void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
5593 ASSERT(instr->HasEnvironment());
5594 LEnvironment* env = instr->environment();
5600 void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
5601 Deoptimizer::BailoutType type = instr->hydrogen()->type();
5610 Comment(";;; deoptimize: %s", instr->hydrogen()->reason());
5611 DeoptimizeIf(no_condition, instr->environment(), type);
5615 void LCodeGen::DoDummy(LDummy* instr) {
5620 void LCodeGen::DoDummyUse(LDummyUse* instr) {
5625 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
5629 RecordSafepointWithLazyDeopt(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0);
5630 ASSERT(instr->HasEnvironment());
5631 LEnvironment* env = instr->environment();
5636 void LCodeGen::DoStackCheck(LStackCheck* instr) {
5639 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
5640 : LDeferredCode(codegen), instr_(instr) { }
5644 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5649 ASSERT(instr->HasEnvironment());
5650 LEnvironment* env = instr->environment();
5653 if (instr->hydrogen()->is_function_entry()) {
5659 ASSERT(instr->context()->IsRegister());
5660 ASSERT(ToRegister(instr->context()).is(rsi));
5663 instr);
5666 ASSERT(instr->hydrogen()->is_backwards_branch());
5669 new(zone()) DeferredStackCheck(this, instr);
5673 __ bind(instr->done_label());
5674 deferred_stack_check->SetExit(instr->done_label());
5683 void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
5687 LEnvironment* environment = instr->environment();
5698 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
5699 ASSERT(ToRegister(instr->context()).is(rsi));
5701 DeoptimizeIf(equal, instr->environment());
5706 DeoptimizeIf(equal, instr->environment());
5709 DeoptimizeIf(cc, instr->environment());
5713 DeoptimizeIf(below_equal, instr->environment());
5724 CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr);
5728 DeoptimizeIf(not_equal, instr->environment());
5733 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) {
5734 Register map = ToRegister(instr->map());
5735 Register result = ToRegister(instr->result());
5747 FieldOperand(result, FixedArray::SizeFor(instr->idx())));
5750 DeoptimizeIf(cc, instr->environment());
5754 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
5755 Register object = ToRegister(instr->value());
5756 __ cmpp(ToRegister(instr->map()),
5758 DeoptimizeIf(not_equal, instr->environment());
5762 void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
5771 instr->pointer_map(), 2, Safepoint::kNoLazyDeopt);
5776 void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
5780 LLoadFieldByIndex* instr,
5784 instr_(instr),
5791 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5798 Register object = ToRegister(instr->object());
5799 Register index = ToRegister(instr->index());
5802 deferred = new(zone()) DeferredLoadMutableDouble(this, instr, object, index);
5833 void LCodeGen::DoStoreFrameContext(LStoreFrameContext* instr) {
5834 Register context = ToRegister(instr->context());
5839 void LCodeGen::DoAllocateBlockContext(LAllocateBlockContext* instr) {
5840 Handle<ScopeInfo> scope_info = instr->scope_info();
5842 __ Push(ToRegister(instr->function()));
5843 CallRuntime(Runtime::kHiddenPushBlockContext, 2, instr);