Lines Matching defs:instr

367 void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
368 if (instr->IsCall()) {
371 if (!instr->IsLazyBailout() && !instr->IsGap()) {
377 void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) { }
440 code->instr()->hydrogen_value()->id(),
441 code->instr()->Mnemonic());
719 LInstruction* instr,
721 DCHECK(instr != NULL);
723 RecordSafepointWithLazyDeopt(instr, safepoint_mode);
736 LInstruction* instr) {
737 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT);
743 LInstruction* instr,
745 DCHECK(instr != NULL);
746 DCHECK(instr->HasPointerMap());
750 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
774 LInstruction* instr,
780 instr->pointer_map(), argc, Safepoint::kNoLazyDeopt);
823 void LCodeGen::DeoptimizeIf(Condition cc, LInstruction* instr,
826 LEnvironment* environment = instr->environment();
866 Deoptimizer::Reason reason(instr->hydrogen_value()->position().raw(),
867 instr->Mnemonic(), detail);
890 void LCodeGen::DeoptimizeIf(Condition cc, LInstruction* instr,
895 DeoptimizeIf(cc, instr, detail, bailout_type);
970 LInstruction* instr, SafepointMode safepoint_mode) {
972 RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt);
976 instr->pointer_map(), 0, Safepoint::kLazyDeopt);
1062 void LCodeGen::DoInstructionGap(LInstructionGap* instr) {
1063 DoGap(instr);
1067 void LCodeGen::DoParameter(LParameter* instr) {
1072 void LCodeGen::DoCallStub(LCallStub* instr) {
1073 DCHECK(ToRegister(instr->context()).is(esi));
1074 DCHECK(ToRegister(instr->result()).is(eax));
1075 switch (instr->hydrogen()->major_key()) {
1078 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1083 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1088 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1097 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
1102 void LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) {
1103 Register dividend = ToRegister(instr->dividend());
1104 int32_t divisor = instr->divisor();
1105 DCHECK(dividend.is(ToRegister(instr->result())));
1113 HMod* hmod = instr->hydrogen();
1124 DeoptimizeIf(zero, instr, "minus zero");
1135 void LCodeGen::DoModByConstI(LModByConstI* instr) {
1136 Register dividend = ToRegister(instr->dividend());
1137 int32_t divisor = instr->divisor();
1138 DCHECK(ToRegister(instr->result()).is(eax));
1141 DeoptimizeIf(no_condition, instr, "division by zero");
1151 HMod* hmod = instr->hydrogen();
1156 DeoptimizeIf(less, instr, "minus zero");
1162 void LCodeGen::DoModI(LModI* instr) {
1163 HMod* hmod = instr->hydrogen();
1165 Register left_reg = ToRegister(instr->left());
1167 Register right_reg = ToRegister(instr->right());
1170 Register result_reg = ToRegister(instr->result());
1178 DeoptimizeIf(zero, instr, "division by zero");
1189 DeoptimizeIf(equal, instr, "minus zero");
1208 DeoptimizeIf(zero, instr, "minus zero");
1217 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
1218 Register dividend = ToRegister(instr->dividend());
1219 int32_t divisor = instr->divisor();
1220 Register result = ToRegister(instr->result());
1225 HDiv* hdiv = instr->hydrogen();
1228 DeoptimizeIf(zero, instr, "minus zero");
1233 DeoptimizeIf(zero, instr, "overflow");
1240 DeoptimizeIf(not_zero, instr, "lost precision");
1255 void LCodeGen::DoDivByConstI(LDivByConstI* instr) {
1256 Register dividend = ToRegister(instr->dividend());
1257 int32_t divisor = instr->divisor();
1258 DCHECK(ToRegister(instr->result()).is(edx));
1261 DeoptimizeIf(no_condition, instr, "division by zero");
1266 HDiv* hdiv = instr->hydrogen();
1269 DeoptimizeIf(zero, instr, "minus zero");
1279 DeoptimizeIf(not_equal, instr, "lost precision");
1285 void LCodeGen::DoDivI(LDivI* instr) {
1286 HBinaryOperation* hdiv = instr->hydrogen();
1287 Register dividend = ToRegister(instr->dividend());
1288 Register divisor = ToRegister(instr->divisor());
1289 Register remainder = ToRegister(instr->temp());
1292 DCHECK(ToRegister(instr->result()).is(eax));
1299 DeoptimizeIf(zero, instr, "division by zero");
1308 DeoptimizeIf(sign, instr, "minus zero");
1318 DeoptimizeIf(zero, instr, "overflow");
1329 DeoptimizeIf(not_zero, instr, "lost precision");
1334 void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
1335 Register dividend = ToRegister(instr->dividend());
1336 int32_t divisor = instr->divisor();
1337 DCHECK(dividend.is(ToRegister(instr->result())));
1350 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1351 DeoptimizeIf(zero, instr, "minus zero");
1356 if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
1357 DeoptimizeIf(overflow, instr, "overflow");
1363 if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
1378 void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
1379 Register dividend = ToRegister(instr->dividend());
1380 int32_t divisor = instr->divisor();
1381 DCHECK(ToRegister(instr->result()).is(edx));
1384 DeoptimizeIf(no_condition, instr, "division by zero");
1389 HMathFloorOfDiv* hdiv = instr->hydrogen();
1392 DeoptimizeIf(zero, instr, "minus zero");
1406 Register temp = ToRegister(instr->temp3());
1424 void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) {
1425 HBinaryOperation* hdiv = instr->hydrogen();
1426 Register dividend = ToRegister(instr->dividend());
1427 Register divisor = ToRegister(instr->divisor());
1428 Register remainder = ToRegister(instr->temp());
1429 Register result = ToRegister(instr->result());
1439 DeoptimizeIf(zero, instr, "division by zero");
1448 DeoptimizeIf(sign, instr, "minus zero");
1458 DeoptimizeIf(zero, instr, "overflow");
1476 void LCodeGen::DoMulI(LMulI* instr) {
1477 Register left = ToRegister(instr->left());
1478 LOperand* right = instr->right();
1480 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1481 __ mov(ToRegister(instr->temp()), left);
1495 } else if (!instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1529 if (instr->hydrogen()->representation().IsSmi()) {
1535 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1536 DeoptimizeIf(overflow, instr, "overflow");
1539 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1546 DeoptimizeIf(no_condition, instr, "minus zero");
1548 __ cmp(ToRegister(instr->temp()), Immediate(0));
1549 DeoptimizeIf(less, instr, "minus zero");
1553 __ or_(ToRegister(instr->temp()), ToOperand(right));
1554 DeoptimizeIf(sign, instr, "minus zero");
1561 void LCodeGen::DoBitI(LBitI* instr) {
1562 LOperand* left = instr->left();
1563 LOperand* right = instr->right();
1564 DCHECK(left->Equals(instr->result()));
1570 instr->hydrogen()->representation());
1571 switch (instr->op()) {
1590 switch (instr->op()) {
1608 void LCodeGen::DoShiftI(LShiftI* instr) {
1609 LOperand* left = instr->left();
1610 LOperand* right = instr->right();
1611 DCHECK(left->Equals(instr->result()));
1616 switch (instr->op()) {
1625 if (instr->can_deopt()) {
1627 DeoptimizeIf(sign, instr, "negative value");
1640 switch (instr->op()) {
1642 if (shift_count == 0 && instr->can_deopt()) {
1644 DeoptimizeIf(sign, instr, "negative value");
1657 } else if (instr->can_deopt()) {
1659 DeoptimizeIf(sign, instr, "negative value");
1664 if (instr->hydrogen_value()->representation().IsSmi() &&
1665 instr->can_deopt()) {
1670 DeoptimizeIf(overflow, instr, "overflow");
1684 void LCodeGen::DoSubI(LSubI* instr) {
1685 LOperand* left = instr->left();
1686 LOperand* right = instr->right();
1687 DCHECK(left->Equals(instr->result()));
1691 ToImmediate(right, instr->hydrogen()->representation()));
1695 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1696 DeoptimizeIf(overflow, instr, "overflow");
1701 void LCodeGen::DoConstantI(LConstantI* instr) {
1702 __ Move(ToRegister(instr->result()), Immediate(instr->value()));
1706 void LCodeGen::DoConstantS(LConstantS* instr) {
1707 __ Move(ToRegister(instr->result()), Immediate(instr->value()));
1711 void LCodeGen::DoConstantD(LConstantD* instr) {
1712 double v = instr->value();
1716 DCHECK(instr->result()->IsDoubleRegister());
1718 XMMRegister res = ToDoubleRegister(instr->result());
1722 Register temp = ToRegister(instr->temp());
1750 void LCodeGen::DoConstantE(LConstantE* instr) {
1751 __ lea(ToRegister(instr->result()), Operand::StaticVariable(instr->value()));
1755 void LCodeGen::DoConstantT(LConstantT* instr) {
1756 Register reg = ToRegister(instr->result());
1757 Handle<Object> object = instr->value(isolate());
1763 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1764 Register result = ToRegister(instr->result());
1765 Register map = ToRegister(instr->value());
1770 void LCodeGen::DoDateField(LDateField* instr) {
1771 Register object = ToRegister(instr->date());
1772 Register result = ToRegister(instr->result());
1773 Register scratch = ToRegister(instr->temp());
1774 Smi* index = instr->index();
1780 DeoptimizeIf(zero, instr, "Smi");
1782 DeoptimizeIf(not_equal, instr, "not a date object");
1825 void LCodeGen::DoSeqStringGetChar(LSeqStringGetChar* instr) {
1826 String::Encoding encoding = instr->hydrogen()->encoding();
1827 Register result = ToRegister(instr->result());
1828 Register string = ToRegister(instr->string());
1844 Operand operand = BuildSeqStringOperand(string, instr->index(), encoding);
1853 void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
1854 String::Encoding encoding = instr->hydrogen()->encoding();
1855 Register string = ToRegister(instr->string());
1858 Register value = ToRegister(instr->value());
1859 Register index = ToRegister(instr->index());
1863 instr->hydrogen()->encoding() == String::ONE_BYTE_ENCODING
1868 Operand operand = BuildSeqStringOperand(string, instr->index(), encoding);
1869 if (instr->value()->IsConstantOperand()) {
1870 int value = ToRepresentation(LConstantOperand::cast(instr->value()),
1881 Register value = ToRegister(instr->value());
1891 void LCodeGen::DoAddI(LAddI* instr) {
1892 LOperand* left = instr->left();
1893 LOperand* right = instr->right();
1895 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) {
1898 instr->hydrogen()->representation());
1899 __ lea(ToRegister(instr->result()), MemOperand(ToRegister(left), offset));
1902 __ lea(ToRegister(instr->result()), address);
1907 ToImmediate(right, instr->hydrogen()->representation()));
1911 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1912 DeoptimizeIf(overflow, instr, "overflow");
1918 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
1919 LOperand* left = instr->left();
1920 LOperand* right = instr->right();
1921 DCHECK(left->Equals(instr->result()));
1922 HMathMinMax::Operation operation = instr->hydrogen()->operation();
1923 if (instr->hydrogen()->representation().IsSmiOrInteger32()) {
1930 Immediate immediate = ToImmediate(LConstantOperand::cast(instr->right()),
1931 instr->hydrogen()->representation());
1944 DCHECK(instr->hydrogen()->representation().IsDouble());
1980 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1981 XMMRegister left = ToDoubleRegister(instr->left());
1982 XMMRegister right = ToDoubleRegister(instr->right());
1983 XMMRegister result = ToDoubleRegister(instr->result());
1984 switch (instr->op()) {
2024 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
2025 DCHECK(ToRegister(instr->context()).is(esi));
2026 DCHECK(ToRegister(instr->left()).is(edx));
2027 DCHECK(ToRegister(instr->right()).is(eax));
2028 DCHECK(ToRegister(instr->result()).is(eax));
2031 CodeFactory::BinaryOpIC(isolate(), instr->op(), NO_OVERWRITE).code();
2032 CallCode(code, RelocInfo::CODE_TARGET, instr);
2037 void LCodeGen::EmitBranch(InstrType instr, Condition cc) {
2038 int left_block = instr->TrueDestination(chunk_);
2039 int right_block = instr->FalseDestination(chunk_);
2057 void LCodeGen::EmitFalseBranch(InstrType instr, Condition cc) {
2058 int false_block = instr->FalseDestination(chunk_);
2067 void LCodeGen::DoBranch(LBranch* instr) {
2068 Representation r = instr->hydrogen()->value()->representation();
2070 Register reg = ToRegister(instr->value());
2072 EmitBranch(instr, not_zero);
2075 XMMRegister reg = ToDoubleRegister(instr->value());
2079 EmitBranch(instr, not_equal);
2082 Register reg = ToRegister(instr->value());
2083 HType type = instr->hydrogen()->value()->type();
2087 EmitBranch(instr, equal);
2091 EmitBranch(instr, not_equal);
2094 EmitBranch(instr, no_condition);
2100 EmitBranch(instr, not_equal);
2104 EmitBranch(instr, not_equal);
2106 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
2112 __ j(equal, instr->FalseLabel(chunk_));
2117 __ j(equal, instr->TrueLabel(chunk_));
2120 __ j(equal, instr->FalseLabel(chunk_));
2125 __ j(equal, instr->FalseLabel(chunk_));
2131 __ j(equal, instr->FalseLabel(chunk_));
2132 __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
2136 DeoptimizeIf(zero, instr, "Smi");
2141 map = ToRegister(instr->temp());
2149 __ j(not_zero, instr->FalseLabel(chunk_));
2156 __ j(above_equal, instr->TrueLabel(chunk_));
2165 __ j(not_zero, instr->TrueLabel(chunk_));
2166 __ jmp(instr->FalseLabel(chunk_));
2173 __ j(equal, instr->TrueLabel(chunk_));
2185 __ j(zero, instr->FalseLabel(chunk_));
2186 __ jmp(instr->TrueLabel(chunk_));
2193 DeoptimizeIf(no_condition, instr, "unexpected object");
2207 void LCodeGen::DoGoto(LGoto* instr) {
2208 EmitGoto(instr->block_id());
2244 void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) {
2245 LOperand* left = instr->left();
2246 LOperand* right = instr->right();
2248 instr->is_double() ||
2249 instr->hydrogen()->left()->CheckFlag(HInstruction::kUint32) ||
2250 instr->hydrogen()->right()->CheckFlag(HInstruction::kUint32);
2251 Condition cc = TokenToCondition(instr->op(), is_unsigned);
2257 int next_block = EvalComparison(instr->op(), left_val, right_val) ?
2258 instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_);
2261 if (instr->is_double()) {
2265 __ j(parity_even, instr->FalseLabel(chunk_));
2269 ToImmediate(right, instr->hydrogen()->representation()));
2272 ToImmediate(left, instr->hydrogen()->representation()));
2279 EmitBranch(instr, cc);
2284 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
2285 Register left = ToRegister(instr->left());
2287 if (instr->right()->IsConstantOperand()) {
2288 Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right()));
2291 Operand right = ToOperand(instr->right());
2294 EmitBranch(instr, equal);
2298 void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
2299 if (instr->hydrogen()->representation().IsTagged()) {
2300 Register input_reg = ToRegister(instr->object());
2302 EmitBranch(instr, equal);
2306 XMMRegister input_reg = ToDoubleRegister(instr->object());
2308 EmitFalseBranch(instr, parity_odd);
2316 EmitBranch(instr, equal);
2320 void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
2321 Representation rep = instr->hydrogen()->value()->representation();
2323 Register scratch = ToRegister(instr->temp());
2326 XMMRegister value = ToDoubleRegister(instr->value());
2330 EmitFalseBranch(instr, not_equal);
2333 EmitBranch(instr, not_zero);
2335 Register value = ToRegister(instr->value());
2337 __ CheckMap(value, map, instr->FalseLabel(chunk()), DO_SMI_CHECK);
2340 EmitFalseBranch(instr, no_overflow);
2343 EmitBranch(instr, equal);
2371 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
2372 Register reg = ToRegister(instr->value());
2373 Register temp = ToRegister(instr->temp());
2376 reg, temp, instr->FalseLabel(chunk_), instr->TrueLabel(chunk_));
2378 EmitBranch(instr, true_cond);
2396 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
2397 Register reg = ToRegister(instr->value());
2398 Register temp = ToRegister(instr->temp());
2401 instr->hydrogen()->value()->type().IsHeapObject()
2405 reg, temp, instr->FalseLabel(chunk_), check_needed);
2407 EmitBranch(instr, true_cond);
2411 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
2412 Operand input = ToOperand(instr->value());
2415 EmitBranch(instr, zero);
2419 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
2420 Register input = ToRegister(instr->value());
2421 Register temp = ToRegister(instr->temp());
2423 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
2425 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2430 EmitBranch(instr, not_zero);
2454 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
2455 Token::Value op = instr->op();
2458 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2463 EmitBranch(instr, condition);
2467 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
2468 InstanceType from = instr->from();
2469 InstanceType to = instr->to();
2476 static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
2477 InstanceType from = instr->from();
2478 InstanceType to = instr->to();
2487 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
2488 Register input = ToRegister(instr->value());
2489 Register temp = ToRegister(instr->temp());
2491 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
2492 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2495 __ CmpObjectType(input, TestType(instr->hydrogen()), temp);
2496 EmitBranch(instr, BranchCondition(instr->hydrogen()));
2500 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
2501 Register input = ToRegister(instr->value());
2502 Register result = ToRegister(instr->result());
2512 LHasCachedArrayIndexAndBranch* instr) {
2513 Register input = ToRegister(instr->value());
2517 EmitBranch(instr, equal);
2586 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2587 Register input = ToRegister(instr->value());
2588 Register temp = ToRegister(instr->temp());
2589 Register temp2 = ToRegister(instr->temp2());
2591 Handle<String> class_name = instr->hydrogen()->class_name();
2593 EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
2596 EmitBranch(instr, equal);
2600 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
2601 Register reg = ToRegister(instr->value());
2602 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map());
2603 EmitBranch(instr, equal);
2607 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
2609 DCHECK(ToRegister(instr->context()).is(esi));
2611 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2616 __ mov(ToRegister(instr->result()), factory()->false_value());
2619 __ mov(ToRegister(instr->result()), factory()->true_value());
2624 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
2628 LInstanceOfKnownGlobal* instr)
2629 : LDeferredCode(codegen), instr_(instr) { }
2633 virtual LInstruction* instr() OVERRIDE { return instr_; }
2641 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
2644 Register object = ToRegister(instr->value());
2645 Register temp = ToRegister(instr->temp());
2654 Register map = ToRegister(instr->temp());
2678 __ mov(ToRegister(instr->result()), factory()->false_value());
2687 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
2704 Register temp = ToRegister(instr->temp());
2706 __ LoadHeapObject(InstanceofStub::right(), instr->function());
2713 instr,
2717 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment();
2725 void LCodeGen::DoCmpT(LCmpT* instr) {
2726 Token::Value op = instr->op();
2729 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2735 __ mov(ToRegister(instr->result()), factory()->false_value());
2738 __ mov(ToRegister(instr->result()), factory()->true_value());
2743 void LCodeGen::EmitReturn(LReturn* instr, bool dynamic_frame_alignment) {
2746 if (instr->has_constant_parameter_count()) {
2747 int parameter_count = ToInteger32(instr->constant_parameter_count());
2756 Register reg = ToRegister(instr->parameter_count());
2768 // emit code to restore stack based on instr->parameter_count()
2780 void LCodeGen::DoReturn(LReturn* instr) {
2807 EmitReturn(instr, true);
2811 EmitReturn(instr, false);
2818 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
2819 Register result = ToRegister(instr->result());
2820 __ mov(result, Operand::ForCell(instr->hydrogen()->cell().handle()));
2821 if (instr->hydrogen()->RequiresHoleCheck()) {
2823 DeoptimizeIf(equal, instr, "hole");
2829 void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
2831 Register vector = ToRegister(instr->temp_vector());
2833 __ mov(vector, instr->hydrogen()->feedback_vector());
2837 Immediate(Smi::FromInt(instr->hydrogen()->slot())));
2841 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
2842 DCHECK(ToRegister(instr->context()).is(esi));
2843 DCHECK(ToRegister(instr->global_object())
2845 DCHECK(ToRegister(instr->result()).is(eax));
2847 __ mov(LoadDescriptor::NameRegister(), instr->name());
2849 EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
2851 ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
2853 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2857 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
2858 Register value = ToRegister(instr->value());
2859 Handle<PropertyCell> cell_handle = instr->hydrogen()->cell().handle();
2865 if (instr->hydrogen()->RequiresHoleCheck()) {
2867 DeoptimizeIf(equal, instr, "hole");
2876 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
2877 Register context = ToRegister(instr->context());
2878 Register result = ToRegister(instr->result());
2879 __ mov(result, ContextOperand(context, instr->slot_index()));
2881 if (instr->hydrogen()->RequiresHoleCheck()) {
2883 if (instr->hydrogen()->DeoptimizesOnHole()) {
2884 DeoptimizeIf(equal, instr, "hole");
2895 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
2896 Register context = ToRegister(instr->context());
2897 Register value = ToRegister(instr->value());
2901 Operand target = ContextOperand(context, instr->slot_index());
2902 if (instr->hydrogen()->RequiresHoleCheck()) {
2904 if (instr->hydrogen()->DeoptimizesOnHole()) {
2905 DeoptimizeIf(equal, instr, "hole");
2912 if (instr->hydrogen()->NeedsWriteBarrier()) {
2914 instr->hydrogen()->value()->type().IsHeapObject()
2916 Register temp = ToRegister(instr->temp());
2917 int offset = Context::SlotOffset(instr->slot_index());
2931 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
2932 HObjectAccess access = instr->hydrogen()->access();
2936 Register result = ToRegister(instr->result());
2937 MemOperand operand = instr->object()->IsConstantOperand()
2939 LConstantOperand::cast(instr->object())))
2940 : MemOperand(ToRegister(instr->object()), offset);
2945 Register object = ToRegister(instr->object());
2946 if (instr->hydrogen()->representation().IsDouble()) {
2947 XMMRegister result = ToDoubleRegister(instr->result());
2952 Register result = ToRegister(instr->result());
2979 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
2980 DCHECK(ToRegister(instr->context()).is(esi));
2981 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister()));
2982 DCHECK(ToRegister(instr->result()).is(eax));
2984 __ mov(LoadDescriptor::NameRegister(), instr->name());
2986 EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
2989 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2993 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
2994 Register function = ToRegister(instr->function());
2995 Register temp = ToRegister(instr->temp());
2996 Register result = ToRegister(instr->result());
3004 DeoptimizeIf(equal, instr, "hole");
3019 void LCodeGen::DoLoadRoot(LLoadRoot* instr) {
3020 Register result = ToRegister(instr->result());
3021 __ LoadRoot(result, instr->index());
3025 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
3026 Register arguments = ToRegister(instr->arguments());
3027 Register result = ToRegister(instr->result());
3028 if (instr->length()->IsConstantOperand() &&
3029 instr->index()->IsConstantOperand()) {
3030 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3031 int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
3035 Register length = ToRegister(instr->length());
3036 Operand index = ToOperand(instr->index());
3045 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
3046 ElementsKind elements_kind = instr->elements_kind();
3047 LOperand* key = instr->key();
3049 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(),
3054 instr->elements(),
3056 instr->hydrogen()->key()->representation(),
3058 instr->base_offset()));
3061 XMMRegister result(ToDoubleRegister(instr->result()));
3066 __ movsd(ToDoubleRegister(instr->result()), operand);
3068 Register result(ToRegister(instr->result()));
3095 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
3097 DeoptimizeIf(negative, instr, "negative value");
3119 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
3120 if (instr->hydrogen()->RequiresHoleCheck()) {
3122 instr->elements(), instr->key(),
3123 instr->hydrogen()->key()->representation(),
3125 instr->base_offset() + sizeof(kHoleNanLower32));
3127 DeoptimizeIf(equal, instr, "hole");
3131 instr->elements(),
3132 instr->key(),
3133 instr->hydrogen()->key()->representation(),
3135 instr->base_offset());
3136 XMMRegister result = ToDoubleRegister(instr->result());
3141 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3142 Register result = ToRegister(instr->result());
3146 BuildFastArrayOperand(instr->elements(), instr->key(),
3147 instr->hydrogen()->key()->representation(),
3148 FAST_ELEMENTS, instr->base_offset()));
3151 if (instr->hydrogen()->RequiresHoleCheck()) {
3152 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
3154 DeoptimizeIf(not_equal, instr, "not a Smi");
3157 DeoptimizeIf(equal, instr, "hole");
3163 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
3164 if (instr->is_typed_elements()) {
3165 DoLoadKeyedExternalArray(instr);
3166 } else if (instr->hydrogen()->representation().IsDouble()) {
3167 DoLoadKeyedFixedDoubleArray(instr);
3169 DoLoadKeyedFixedArray(instr);
3205 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
3206 DCHECK(ToRegister(instr->context()).is(esi));
3207 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister()));
3208 DCHECK(ToRegister(instr->key()).is(LoadDescriptor::NameRegister()));
3211 EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
3215 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3219 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
3220 Register result = ToRegister(instr->result());
3222 if (instr->hydrogen()->from_inlined()) {
3248 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
3249 Operand elem = ToOperand(instr->elements());
3250 Register result = ToRegister(instr->result());
3270 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
3271 Register receiver = ToRegister(instr->receiver());
3272 Register function = ToRegister(instr->function());
3279 Register scratch = ToRegister(instr->temp());
3281 if (!instr->hydrogen()->known_function()) {
3304 DeoptimizeIf(equal, instr, "Smi");
3306 DeoptimizeIf(below, instr, "not a JavaScript object");
3319 void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
3320 Register receiver = ToRegister(instr->receiver());
3321 Register function = ToRegister(instr->function());
3322 Register length = ToRegister(instr->length());
3323 Register elements = ToRegister(instr->elements());
3326 DCHECK(ToRegister(instr->result()).is(eax));
3332 DeoptimizeIf(above, instr, "too many arguments");
3350 DCHECK(instr->HasPointerMap());
3351 LPointerMap* pointers = instr->pointer_map();
3359 void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
3364 void LCodeGen::DoPushArgument(LPushArgument* instr) {
3365 LOperand* argument = instr->value();
3370 void LCodeGen::DoDrop(LDrop* instr) {
3371 __ Drop(instr->count());
3375 void LCodeGen::DoThisFunction(LThisFunction* instr) {
3376 Register result = ToRegister(instr->result());
3381 void LCodeGen::DoContext(LContext* instr) {
3382 Register result = ToRegister(instr->result());
3392 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
3393 DCHECK(ToRegister(instr->context()).is(esi));
3395 __ push(Immediate(instr->hydrogen()->pairs()));
3396 __ push(Immediate(Smi::FromInt(instr->hydrogen()->flags())));
3397 CallRuntime(Runtime::kDeclareGlobals, 3, instr);
3404 LInstruction* instr,
3431 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
3434 LPointerMap* pointers = instr->pointer_map();
3445 LTailCallThroughMegamorphicCache* instr) {
3446 Register receiver = ToRegister(instr->receiver());
3447 Register name = ToRegister(instr->name());
3460 isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(),
3470 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
3471 DCHECK(ToRegister(instr->result()).is(eax));
3473 LPointerMap* pointers = instr->pointer_map();
3476 if (instr->target()->IsConstantOperand()) {
3477 LConstantOperand* target = LConstantOperand::cast(instr->target());
3482 DCHECK(instr->target()->IsRegister());
3483 Register target = ToRegister(instr->target());
3492 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) {
3493 DCHECK(ToRegister(instr->function()).is(edi));
3494 DCHECK(ToRegister(instr->result()).is(eax));
3496 if (instr->hydrogen()->pass_argument_count()) {
3497 __ mov(eax, instr->arity());
3504 if (instr->hydrogen()->function()->IsConstant()) {
3505 HConstant* fun_const = HConstant::cast(instr->hydrogen()->function());
3517 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
3521 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3522 Register input_reg = ToRegister(instr->value());
3525 DeoptimizeIf(not_equal, instr, "not a heap number");
3548 instr, instr->context());
3566 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
3567 Register input_reg = ToRegister(instr->value());
3572 DeoptimizeIf(negative, instr, "overflow");
3577 void LCodeGen::DoMathAbs(LMathAbs* instr) {
3582 LMathAbs* instr)
3583 : LDeferredCode(codegen), instr_(instr) { }
3587 virtual LInstruction* instr() OVERRIDE { return instr_; }
3592 DCHECK(instr->value()->Equals(instr->result()));
3593 Representation r = instr->hydrogen()->value()->representation();
3597 XMMRegister input_reg = ToDoubleRegister(instr->value());
3602 EmitIntegerMathAbs(instr);
3605 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
3606 Register input_reg = ToRegister(instr->value());
3609 EmitIntegerMathAbs(instr);
3615 void LCodeGen::DoMathFloor(LMathFloor* instr) {
3617 Register output_reg = ToRegister(instr->result());
3618 XMMRegister input_reg = ToDoubleRegister(instr->value());
3622 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3630 DeoptimizeIf(not_zero, instr, "minus zero");
3637 DeoptimizeIf(overflow, instr, "overflow");
3643 DeoptimizeIf(parity_even, instr, "NaN");
3646 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3652 DeoptimizeIf(not_zero, instr, "minus zero");
3662 DeoptimizeIf(overflow, instr, "overflow");
3673 DeoptimizeIf(overflow, instr, "overflow");
3680 void LCodeGen::DoMathRound(LMathRound* instr) {
3681 Register output_reg = ToRegister(instr->result());
3682 XMMRegister input_reg = ToDoubleRegister(instr->value());
3684 XMMRegister input_temp = ToDoubleRegister(instr->temp());
3701 DeoptimizeIf(overflow, instr, "overflow");
3716 DeoptimizeIf(overflow, instr, "overflow");
3728 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3732 DeoptimizeIf(not_zero, instr, "minus zero");
3739 void LCodeGen::DoMathFround(LMathFround* instr) {
3740 XMMRegister input_reg = ToDoubleRegister(instr->value());
3741 XMMRegister output_reg = ToDoubleRegister(instr->result());
3747 void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
3748 Operand input = ToOperand(instr->value());
3749 XMMRegister output = ToDoubleRegister(instr->result());
3754 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
3756 XMMRegister input_reg = ToDoubleRegister(instr->value());
3757 Register scratch = ToRegister(instr->temp());
3758 DCHECK(ToDoubleRegister(instr->result()).is(input_reg));
3788 void LCodeGen::DoPower(LPower* instr) {
3789 Representation exponent_type = instr->hydrogen()->right()->representation();
3793 DCHECK(!instr->right()->IsDoubleRegister() ||
3794 ToDoubleRegister(instr->right()).is(xmm1));
3795 DCHECK(!instr->right()->IsRegister() ||
3796 ToRegister(instr->right()).is(tagged_exponent));
3797 DCHECK(ToDoubleRegister(instr->left()).is(xmm2));
3798 DCHECK(ToDoubleRegister(instr->result()).is(xmm3));
3808 DeoptimizeIf(not_equal, instr, "not a heap number");
3823 void LCodeGen::DoMathLog(LMathLog* instr) {
3824 DCHECK(instr->value()->Equals(instr->result()));
3825 XMMRegister input_reg = ToDoubleRegister(instr->value());
3854 void LCodeGen::DoMathClz32(LMathClz32* instr) {
3855 Register input = ToRegister(instr->value());
3856 Register result = ToRegister(instr->result());
3868 void LCodeGen::DoMathExp(LMathExp* instr) {
3869 XMMRegister input = ToDoubleRegister(instr->value());
3870 XMMRegister result = ToDoubleRegister(instr->result());
3872 Register temp1 = ToRegister(instr->temp1());
3873 Register temp2 = ToRegister(instr->temp2());
3879 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
3880 DCHECK(ToRegister(instr->context()).is(esi));
3881 DCHECK(ToRegister(instr->function()).is(edi));
3882 DCHECK(instr->HasPointerMap());
3884 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
3886 LPointerMap* pointers = instr->pointer_map();
3889 ParameterCount count(instr->arity());
3893 instr->hydrogen()->formal_parameter_count(),
3894 instr->arity(),
3895 instr,
3901 void LCodeGen::DoCallFunction(LCallFunction* instr) {
3902 DCHECK(ToRegister(instr->context()).is(esi));
3903 DCHECK(ToRegister(instr->function()).is(edi));
3904 DCHECK(ToRegister(instr->result()).is(eax));
3906 int arity = instr->arity();
3907 CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
3908 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
3912 void LCodeGen::DoCallNew(LCallNew* instr) {
3913 DCHECK(ToRegister(instr->context()).is(esi));
3914 DCHECK(ToRegister(instr->constructor()).is(edi));
3915 DCHECK(ToRegister(instr->result()).is(eax));
3920 __ Move(eax, Immediate(instr->arity()));
3921 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
3925 void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
3926 DCHECK(ToRegister(instr->context()).is(esi));
3927 DCHECK(ToRegister(instr->constructor()).is(edi));
3928 DCHECK(ToRegister(instr->result()).is(eax));
3930 __ Move(eax, Immediate(instr->arity()));
3932 ElementsKind kind = instr->hydrogen()->elements_kind();
3938 if (instr->arity() == 0) {
3940 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
3941 } else if (instr->arity() == 1) {
3955 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
3961 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
3965 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
3970 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
3971 DCHECK(ToRegister(instr->context()).is(esi));
3972 CallRuntime(instr->function(), instr->arity(), instr, instr->save_doubles());
3976 void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) {
3977 Register function = ToRegister(instr->function());
3978 Register code_object = ToRegister(instr->code_object());
3984 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
3985 Register result = ToRegister(instr->result());
3986 Register base = ToRegister(instr->base_object());
3987 if (instr->offset()->IsConstantOperand()) {
3988 LConstantOperand* offset = LConstantOperand::cast(instr->offset());
3991 Register offset = ToRegister(instr->offset());
3997 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
3998 Representation representation = instr->hydrogen()->field_representation();
4000 HObjectAccess access = instr->hydrogen()->access();
4004 DCHECK(!instr->hydrogen()->NeedsWriteBarrier());
4005 MemOperand operand = instr->object()->IsConstantOperand()
4007 ToExternalReference(LConstantOperand::cast(instr->object())))
4008 : MemOperand(ToRegister(instr->object()), offset);
4009 if (instr->value()->IsConstantOperand()) {
4010 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4013 Register value = ToRegister(instr->value());
4019 Register object = ToRegister(instr->object());
4023 !instr->value()->IsConstantOperand() ||
4024 IsSmi(LConstantOperand::cast(instr->value())));
4027 DCHECK(!instr->hydrogen()->has_transition());
4028 DCHECK(!instr->hydrogen()->NeedsWriteBarrier());
4029 XMMRegister value = ToDoubleRegister(instr->value());
4034 if (instr->hydrogen()->has_transition()) {
4035 Handle<Map> transition = instr->hydrogen()->transition_map();
4038 if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
4039 Register temp = ToRegister(instr->temp());
4040 Register temp_map = ToRegister(instr->temp_map());
4049 write_register = ToRegister(instr->temp());
4054 if (instr->value()->IsConstantOperand()) {
4055 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4061 DCHECK(!instr->hydrogen()->NeedsWriteBarrier());
4065 DCHECK(!instr->hydrogen()->NeedsWriteBarrier());
4069 Register value = ToRegister(instr->value());
4073 if (instr->hydrogen()->NeedsWriteBarrier()) {
4074 Register value = ToRegister(instr->value());
4075 Register temp = access.IsInobject() ? ToRegister(instr->temp()) : object;
4083 instr->hydrogen()->SmiCheckForWriteBarrier(),
4084 instr->hydrogen()->PointersToHereCheckForValue());
4089 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
4090 DCHECK(ToRegister(instr->context()).is(esi));
4091 DCHECK(ToRegister(instr->object()).is(StoreDescriptor::ReceiverRegister()));
4092 DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister()));
4094 __ mov(StoreDescriptor::NameRegister(), instr->name());
4095 Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode());
4096 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4100 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
4101 Condition cc = instr->hydrogen()->allow_equality() ? above : above_equal;
4102 if (instr->index()->IsConstantOperand()) {
4103 __ cmp(ToOperand(instr->length()),
4104 ToImmediate(LConstantOperand::cast(instr->index()),
4105 instr->hydrogen()->length()->representation()));
4107 } else if (instr->length()->IsConstantOperand()) {
4108 __ cmp(ToOperand(instr->index()),
4109 ToImmediate(LConstantOperand::cast(instr->length()),
4110 instr->hydrogen()->index()->representation()));
4112 __ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
4114 if (FLAG_debug_code && instr->hydrogen()->skip_check()) {
4120 DeoptimizeIf(cc, instr, "out of bounds");
4125 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4126 ElementsKind elements_kind = instr->elements_kind();
4127 LOperand* key = instr->key();
4129 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(),
4134 instr->elements(),
4136 instr->hydrogen()->key()->representation(),
4138 instr->base_offset()));
4142 __ cvtsd2ss(xmm_scratch, ToDoubleRegister(instr->value()));
4146 __ movsd(operand, ToDoubleRegister(instr->value()));
4148 Register value = ToRegister(instr->value());
4189 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
4193 instr->elements(),
4194 instr->key(),
4195 instr->hydrogen()->key()->representation(),
4197 instr->base_offset());
4199 XMMRegister value = ToDoubleRegister(instr->value());
4201 if (instr->NeedsCanonicalization()) {
4215 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4216 Register elements = ToRegister(instr->elements());
4217 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
4220 instr->elements(),
4221 instr->key(),
4222 instr->hydrogen()->key()->representation(),
4224 instr->base_offset());
4225 if (instr->value()->IsRegister()) {
4226 __ mov(operand, ToRegister(instr->value()));
4228 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4239 if (instr->hydrogen()->NeedsWriteBarrier()) {
4240 DCHECK(instr->value()->IsRegister());
4241 Register value = ToRegister(instr->value());
4242 DCHECK(!instr->key()->IsConstantOperand());
4244 instr->hydrogen()->value()->type().IsHeapObject()
4254 instr->hydrogen()->PointersToHereCheckForValue());
4259 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
4261 if (instr->is_typed_elements()) {
4262 DoStoreKeyedExternalArray(instr);
4263 } else if (instr->hydrogen()->value()->representation().IsDouble()) {
4264 DoStoreKeyedFixedDoubleArray(instr);
4266 DoStoreKeyedFixedArray(instr);
4271 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
4272 DCHECK(ToRegister(instr->context()).is(esi));
4273 DCHECK(ToRegister(instr->object()).is(StoreDescriptor::ReceiverRegister()));
4274 DCHECK(ToRegister(instr->key()).is(StoreDescriptor::NameRegister()));
4275 DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister()));
4278 CodeFactory::KeyedStoreIC(isolate(), instr->strict_mode()).code();
4279 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4283 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
4284 Register object = ToRegister(instr->object());
4285 Register temp = ToRegister(instr->temp());
4288 DeoptimizeIf(equal, instr, "memento found");
4293 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
4294 Register object_reg = ToRegister(instr->object());
4296 Handle<Map> from_map = instr->original_map();
4297 Handle<Map> to_map = instr->transitioned_map();
4298 ElementsKind from_kind = instr->from_kind();
4299 ElementsKind to_kind = instr->to_kind();
4309 Register new_map_reg = ToRegister(instr->new_map_temp());
4313 DCHECK_NE(instr->temp(), NULL);
4315 ToRegister(instr->temp()),
4318 DCHECK(ToRegister(instr->context()).is(esi));
4325 RecordSafepointWithLazyDeopt(instr,
4332 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
4336 LStringCharCodeAt* instr)
4337 : LDeferredCode(codegen), instr_(instr) { }
4341 virtual LInstruction* instr() OVERRIDE { return instr_; }
4347 new(zone()) DeferredStringCharCodeAt(this, instr);
4351 ToRegister(instr->string()),
4352 ToRegister(instr->index()),
4353 ToRegister(instr->result()),
4359 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
4360 Register string = ToRegister(instr->string());
4361 Register result = ToRegister(instr->result());
4373 if (instr->index()->IsConstantOperand()) {
4374 Immediate immediate = ToImmediate(LConstantOperand::cast(instr->index()),
4378 Register index = ToRegister(instr->index());
4383 instr, instr->context());
4390 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
4394 LStringCharFromCode* instr)
4395 : LDeferredCode(codegen), instr_(instr) { }
4399 virtual LInstruction* instr() OVERRIDE { return instr_; }
4405 new(zone()) DeferredStringCharFromCode(this, instr);
4407 DCHECK(instr->hydrogen()->value()->representation().IsInteger32());
4408 Register char_code = ToRegister(instr->char_code());
4409 Register result = ToRegister(instr->result());
4424 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
4425 Register char_code = ToRegister(instr->char_code());
4426 Register result = ToRegister(instr->result());
4436 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context());
4441 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4442 DCHECK(ToRegister(instr->context()).is(esi));
4443 DCHECK(ToRegister(instr->left()).is(edx));
4444 DCHECK(ToRegister(instr->right()).is(eax));
4446 instr->hydrogen()->flags(),
4447 instr->hydrogen()->pretenure_flag());
4448 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
4452 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4453 LOperand* input = instr->value();
4454 LOperand* output = instr->result();
4461 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4462 LOperand* input = instr->value();
4463 LOperand* output = instr->result();
4468 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4472 LNumberTagI* instr)
4473 : LDeferredCode(codegen), instr_(instr) { }
4478 virtual LInstruction* instr() OVERRIDE { return instr_; }
4483 LOperand* input = instr->value();
4484 DCHECK(input->IsRegister() && input->Equals(instr->result()));
4488 new(zone()) DeferredNumberTagI(this, instr);
4495 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4498 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
4499 : LDeferredCode(codegen), instr_(instr) { }
4504 virtual LInstruction* instr() OVERRIDE { return instr_; }
4509 LOperand* input = instr->value();
4510 DCHECK(input->IsRegister() && input->Equals(instr->result()));
4514 new(zone()) DeferredNumberTagU(this, instr);
4522 void LCodeGen::DoDeferredNumberTagIU(LInstruction* instr,
4566 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4577 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
4580 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4581 : LDeferredCode(codegen), instr_(instr) { }
4585 virtual LInstruction* instr() OVERRIDE { return instr_; }
4590 Register reg = ToRegister(instr->result());
4593 new(zone()) DeferredNumberTagD(this, instr);
4595 Register tmp = ToRegister(instr->temp());
4601 XMMRegister input_reg = ToDoubleRegister(instr->value());
4606 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
4610 Register reg = ToRegister(instr->result());
4622 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4627 void LCodeGen::DoSmiTag(LSmiTag* instr) {
4628 HChange* hchange = instr->hydrogen();
4629 Register input = ToRegister(instr->value());
4633 DeoptimizeIf(not_zero, instr, "overflow");
4638 DeoptimizeIf(overflow, instr, "overflow");
4643 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
4644 LOperand* input = instr->value();
4646 DCHECK(input->IsRegister() && input->Equals(instr->result()));
4647 if (instr->needs_check()) {
4649 DeoptimizeIf(not_zero, instr, "not a Smi");
4657 void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg,
4661 instr->hydrogen()->can_convert_undefined_to_nan();
4662 bool deoptimize_on_minus_zero = instr->hydrogen()->deoptimize_on_minus_zero();
4676 DeoptimizeIf(not_equal, instr, "not a heap number");
4689 DeoptimizeIf(not_zero, instr, "minus zero");
4698 DeoptimizeIf(not_equal, instr, "not a heap number/undefined");
4719 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) {
4720 Register input_reg = ToRegister(instr->value());
4726 if (instr->truncating()) {
4752 DeoptimizeIf(not_equal, instr, "not a heap number/undefined/true/false");
4755 XMMRegister scratch = ToDoubleRegister(instr->temp());
4759 DeoptimizeIf(not_equal, instr, "not a heap number");
4764 DeoptimizeIf(not_equal, instr, "lost precision");
4765 DeoptimizeIf(parity_even, instr, "NaN");
4766 if (instr->hydrogen()->GetMinusZeroMode() == FAIL_ON_MINUS_ZERO) {
4771 DeoptimizeIf(not_zero, instr, "minus zero");
4777 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
4780 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
4781 : LDeferredCode(codegen), instr_(instr) { }
4785 virtual LInstruction* instr() OVERRIDE { return instr_; }
4790 LOperand* input = instr->value();
4793 DCHECK(input_reg.is(ToRegister(instr->result())));
4795 if (instr->hydrogen()->value()->representation().IsSmi()) {
4799 new(zone()) DeferredTaggedToI(this, instr);
4812 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
4813 LOperand* input = instr->value();
4815 LOperand* temp = instr->temp();
4817 LOperand* result = instr->result();
4823 HValue* value = instr->hydrogen()->value();
4828 EmitNumberUntagD(instr, input_reg, temp_reg, result_reg, mode);
4832 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
4833 LOperand* input = instr->value();
4835 LOperand* result = instr->result();
4839 if (instr->truncating()) {
4848 instr->hydrogen()->GetMinusZeroMode(), &lost_precision,
4852 DeoptimizeIf(no_condition, instr, "lost precision");
4854 DeoptimizeIf(no_condition, instr, "NaN");
4856 DeoptimizeIf(no_condition, instr, "minus zero");
4862 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
4863 LOperand* input = instr->value();
4865 LOperand* result = instr->result();
4874 instr->hydrogen()->GetMinusZeroMode(), &lost_precision, &is_nan,
4878 DeoptimizeIf(no_condition, instr, "lost precision");
4880 DeoptimizeIf(no_condition, instr, "NaN");
4882 DeoptimizeIf(no_condition, instr, "minus zero");
4885 DeoptimizeIf(overflow, instr, "overflow");
4889 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
4890 LOperand* input = instr->value();
4892 DeoptimizeIf(not_zero, instr, "not a Smi");
4896 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
4897 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
4898 LOperand* input = instr->value();
4900 DeoptimizeIf(zero, instr, "Smi");
4905 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
4906 Register input = ToRegister(instr->value());
4907 Register temp = ToRegister(instr->temp());
4911 if (instr->hydrogen()->is_interval_check()) {
4914 instr->hydrogen()->GetCheckInterval(&first, &last);
4921 DeoptimizeIf(not_equal, instr, "wrong instance type");
4923 DeoptimizeIf(below, instr, "wrong instance type");
4928 DeoptimizeIf(above, instr, "wrong instance type");
4934 instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
4939 DeoptimizeIf(tag == 0 ? not_zero : zero, instr, "wrong instance type");
4944 DeoptimizeIf(not_equal, instr, "wrong instance type");
4950 void LCodeGen::DoCheckValue(LCheckValue* instr) {
4951 Handle<HeapObject> object = instr->hydrogen()->object().handle();
4952 if (instr->hydrogen()->object_in_new_space()) {
4953 Register reg = ToRegister(instr->value());
4957 Operand operand = ToOperand(instr->value());
4960 DeoptimizeIf(not_equal, instr, "value mismatch");
4964 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
4971 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt);
4975 DeoptimizeIf(zero, instr, "instance migration failed");
4979 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
4982 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object)
4983 : LDeferredCode(codegen), instr_(instr), object_(object) {
4990 virtual LInstruction* instr() OVERRIDE { return instr_; }
4997 if (instr->hydrogen()->IsStabilityCheck()) {
4998 const UniqueSet<Map>* maps = instr->hydrogen()->maps();
5005 LOperand* input = instr->value();
5010 if (instr->hydrogen()->HasMigrationTarget()) {
5011 deferred = new(zone()) DeferredCheckMaps(this, instr, reg);
5015 const UniqueSet<Map>* maps = instr->hydrogen()->maps();
5025 if (instr->hydrogen()->HasMigrationTarget()) {
5028 DeoptimizeIf(not_equal, instr, "wrong map");
5035 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
5036 XMMRegister value_reg = ToDoubleRegister(instr->unclamped());
5038 Register result_reg = ToRegister(instr->result());
5043 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
5044 DCHECK(instr->unclamped()->Equals(instr->result()));
5045 Register value_reg = ToRegister(instr->result());
5050 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
5051 DCHECK(instr->unclamped()->Equals(instr->result()));
5052 Register input_reg = ToRegister(instr->unclamped());
5053 XMMRegister temp_xmm_reg = ToDoubleRegister(instr->temp_xmm());
5067 DeoptimizeIf(not_equal, instr, "not a heap number/undefined");
5085 void LCodeGen::DoDoubleBits(LDoubleBits* instr) {
5086 XMMRegister value_reg = ToDoubleRegister(instr->value());
5087 Register result_reg = ToRegister(instr->result());
5088 if (instr->hydrogen()->bits() == HDoubleBits::HIGH) {
5103 void LCodeGen::DoConstructDouble(LConstructDouble* instr) {
5104 Register hi_reg = ToRegister(instr->hi());
5105 Register lo_reg = ToRegister(instr->lo());
5106 XMMRegister result_reg = ToDoubleRegister(instr->result());
5122 void LCodeGen::DoAllocate(LAllocate* instr) {
5125 DeferredAllocate(LCodeGen* codegen, LAllocate* instr)
5126 : LDeferredCode(codegen), instr_(instr) { }
5130 virtual LInstruction* instr() OVERRIDE { return instr_; }
5135 DeferredAllocate* deferred = new(zone()) DeferredAllocate(this, instr);
5137 Register result = ToRegister(instr->result());
5138 Register temp = ToRegister(instr->temp());
5142 if (instr->hydrogen()->MustAllocateDoubleAligned()) {
5145 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5146 DCHECK(!instr->hydrogen()->IsOldDataSpaceAllocation());
5147 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
5149 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5150 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
5154 if (instr->size()->IsConstantOperand()) {
5155 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5162 Register size = ToRegister(instr->size());
5168 if (instr->hydrogen()->MustPrefillWithFiller()) {
5169 if (instr->size()->IsConstantOperand()) {
5170 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5173 temp = ToRegister(instr->size());
5187 void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
5188 Register result = ToRegister(instr->result());
5196 if (instr->size()->IsRegister()) {
5197 Register size = ToRegister(instr->size());
5199 __ SmiTag(ToRegister(instr->size()));
5202 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5213 instr->hydrogen()->MustAllocateDoubleAligned());
5214 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5215 DCHECK(!instr->hydrogen()->IsOldDataSpaceAllocation());
5216 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
5218 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5219 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
5227 Runtime::kAllocateInTargetSpace, 2, instr, instr->context());
5232 void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
5233 DCHECK(ToRegister(instr->value()).is(eax));
5235 CallRuntime(Runtime::kToFastProperties, 1, instr);
5239 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
5240 DCHECK(ToRegister(instr->context()).is(esi));
5248 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
5249 __ LoadHeapObject(ecx, instr->hydrogen()->literals());
5257 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index())));
5258 __ push(Immediate(instr->hydrogen()->pattern()));
5259 __ push(Immediate(instr->hydrogen()->flags()));
5260 CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr);
5272 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr);
5291 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
5292 DCHECK(ToRegister(instr->context()).is(esi));
5295 bool pretenure = instr->hydrogen()->pretenure();
5296 if (!pretenure && instr->hydrogen()->has_no_literals()) {
5297 FastNewClosureStub stub(isolate(), instr->hydrogen()->strict_mode(),
5298 instr->hydrogen()->kind());
5299 __ mov(ebx, Immediate(instr->hydrogen()->shared_info()));
5300 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
5303 __ push(Immediate(instr->hydrogen()->shared_info()));
5306 CallRuntime(Runtime::kNewClosure, 3, instr);
5311 void LCodeGen::DoTypeof(LTypeof* instr) {
5312 DCHECK(ToRegister(instr->context()).is(esi));
5313 LOperand* input = instr->value();
5315 CallRuntime(Runtime::kTypeof, 1, instr);
5319 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
5320 Register input = ToRegister(instr->value());
5321 Condition final_branch_condition = EmitTypeofIs(instr, input);
5323 EmitBranch(instr, final_branch_condition);
5328 Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) {
5329 Label* true_label = instr->TrueLabel(chunk_);
5330 Label* false_label = instr->FalseLabel(chunk_);
5331 Handle<String> type_name = instr->type_literal();
5332 int left_block = instr->TrueDestination(chunk_);
5333 int right_block = instr->FalseDestination(chunk_);
5404 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
5405 Register temp = ToRegister(instr->temp());
5408 EmitBranch(instr, equal);
5444 void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
5446 DCHECK(instr->HasEnvironment());
5447 LEnvironment* env = instr->environment();
5453 void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
5454 Deoptimizer::BailoutType type = instr->hydrogen()->type();
5462 DeoptimizeIf(no_condition, instr, instr->hydrogen()->reason(), type);
5466 void LCodeGen::DoDummy(LDummy* instr) {
5471 void LCodeGen::DoDummyUse(LDummyUse* instr) {
5476 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
5481 instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
5482 DCHECK(instr->HasEnvironment());
5483 LEnvironment* env = instr->environment();
5488 void LCodeGen::DoStackCheck(LStackCheck* instr) {
5491 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
5492 : LDeferredCode(codegen), instr_(instr) { }
5496 virtual LInstruction* instr() OVERRIDE { return instr_; }
5501 DCHECK(instr->HasEnvironment());
5502 LEnvironment* env = instr->environment();
5505 if (instr->hydrogen()->is_function_entry()) {
5513 DCHECK(instr->context()->IsRegister());
5514 DCHECK(ToRegister(instr->context()).is(esi));
5517 instr);
5520 DCHECK(instr->hydrogen()->is_backwards_branch());
5523 new(zone()) DeferredStackCheck(this, instr);
5529 __ bind(instr->done_label());
5530 deferred_stack_check->SetExit(instr->done_label());
5539 void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
5543 LEnvironment* environment = instr->environment();
5554 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
5555 DCHECK(ToRegister(instr->context()).is(esi));
5557 DeoptimizeIf(equal, instr, "undefined");
5560 DeoptimizeIf(equal, instr, "null");
5563 DeoptimizeIf(zero, instr, "Smi");
5567 DeoptimizeIf(below_equal, instr, "wrong instance type");
5578 CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr);
5582 DeoptimizeIf(not_equal, instr, "wrong map");
5587 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) {
5588 Register map = ToRegister(instr->map());
5589 Register result = ToRegister(instr->result());
5602 FieldOperand(result, FixedArray::SizeFor(instr->idx())));
5605 DeoptimizeIf(equal, instr, "no cache");
5609 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
5610 Register object = ToRegister(instr->value());
5611 __ cmp(ToRegister(instr->map()),
5613 DeoptimizeIf(not_equal, instr, "wrong map");
5617 void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
5626 instr->pointer_map(), 2, Safepoint::kNoLazyDeopt);
5631 void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
5635 LLoadFieldByIndex* instr,
5639 instr_(instr),
5646 virtual LInstruction* instr() OVERRIDE { return instr_; }
5653 Register object = ToRegister(instr->object());
5654 Register index = ToRegister(instr->index());
5658 this, instr, object, index);
5687 void LCodeGen::DoStoreFrameContext(LStoreFrameContext* instr) {
5688 Register context = ToRegister(instr->context());
5693 void LCodeGen::DoAllocateBlockContext(LAllocateBlockContext* instr) {
5694 Handle<ScopeInfo> scope_info = instr->scope_info();
5696 __ push(ToRegister(instr->function()));
5697 CallRuntime(Runtime::kPushBlockContext, 2, instr);