Lines Matching refs:instr
365 void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
366 if (instr->IsCall()) {
369 if (!instr->IsLazyBailout() && !instr->IsGap()) {
375 void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) { }
443 code->instr()->hydrogen_value()->id(),
444 code->instr()->Mnemonic());
722 LInstruction* instr,
724 ASSERT(instr != NULL);
726 RecordSafepointWithLazyDeopt(instr, safepoint_mode);
739 LInstruction* instr) {
740 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT);
746 LInstruction* instr,
748 ASSERT(instr != NULL);
749 ASSERT(instr->HasPointerMap());
753 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
777 LInstruction* instr,
783 instr->pointer_map(), argc, Safepoint::kNoLazyDeopt);
972 LInstruction* instr, SafepointMode safepoint_mode) {
974 RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt);
978 instr->pointer_map(), 0, Safepoint::kLazyDeopt);
1064 void LCodeGen::DoInstructionGap(LInstructionGap* instr) {
1065 DoGap(instr);
1069 void LCodeGen::DoParameter(LParameter* instr) {
1074 void LCodeGen::DoCallStub(LCallStub* instr) {
1075 ASSERT(ToRegister(instr->context()).is(esi));
1076 ASSERT(ToRegister(instr->result()).is(eax));
1077 switch (instr->hydrogen()->major_key()) {
1080 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1085 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1090 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1099 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
1104 void LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) {
1105 Register dividend = ToRegister(instr->dividend());
1106 int32_t divisor = instr->divisor();
1107 ASSERT(dividend.is(ToRegister(instr->result())));
1115 HMod* hmod = instr->hydrogen();
1126 DeoptimizeIf(zero, instr->environment());
1137 void LCodeGen::DoModByConstI(LModByConstI* instr) {
1138 Register dividend = ToRegister(instr->dividend());
1139 int32_t divisor = instr->divisor();
1140 ASSERT(ToRegister(instr->result()).is(eax));
1143 DeoptimizeIf(no_condition, instr->environment());
1153 HMod* hmod = instr->hydrogen();
1158 DeoptimizeIf(less, instr->environment());
1164 void LCodeGen::DoModI(LModI* instr) {
1165 HMod* hmod = instr->hydrogen();
1167 Register left_reg = ToRegister(instr->left());
1169 Register right_reg = ToRegister(instr->right());
1172 Register result_reg = ToRegister(instr->result());
1180 DeoptimizeIf(zero, instr->environment());
1191 DeoptimizeIf(equal, instr->environment());
1210 DeoptimizeIf(zero, instr->environment());
1219 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
1220 Register dividend = ToRegister(instr->dividend());
1221 int32_t divisor = instr->divisor();
1222 Register result = ToRegister(instr->result());
1227 HDiv* hdiv = instr->hydrogen();
1230 DeoptimizeIf(zero, instr->environment());
1235 DeoptimizeIf(zero, instr->environment());
1242 DeoptimizeIf(not_zero, instr->environment());
1257 void LCodeGen::DoDivByConstI(LDivByConstI* instr) {
1258 Register dividend = ToRegister(instr->dividend());
1259 int32_t divisor = instr->divisor();
1260 ASSERT(ToRegister(instr->result()).is(edx));
1263 DeoptimizeIf(no_condition, instr->environment());
1268 HDiv* hdiv = instr->hydrogen();
1271 DeoptimizeIf(zero, instr->environment());
1281 DeoptimizeIf(not_equal, instr->environment());
1287 void LCodeGen::DoDivI(LDivI* instr) {
1288 HBinaryOperation* hdiv = instr->hydrogen();
1289 Register dividend = ToRegister(instr->dividend());
1290 Register divisor = ToRegister(instr->divisor());
1291 Register remainder = ToRegister(instr->temp());
1294 ASSERT(ToRegister(instr->result()).is(eax));
1301 DeoptimizeIf(zero, instr->environment());
1310 DeoptimizeIf(sign, instr->environment());
1320 DeoptimizeIf(zero, instr->environment());
1331 DeoptimizeIf(not_zero, instr->environment());
1336 void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
1337 Register dividend = ToRegister(instr->dividend());
1338 int32_t divisor = instr->divisor();
1339 ASSERT(dividend.is(ToRegister(instr->result())));
1352 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1353 DeoptimizeIf(zero, instr->environment());
1358 if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
1359 DeoptimizeIf(overflow, instr->environment());
1365 if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
1380 void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
1381 Register dividend = ToRegister(instr->dividend());
1382 int32_t divisor = instr->divisor();
1383 ASSERT(ToRegister(instr->result()).is(edx));
1386 DeoptimizeIf(no_condition, instr->environment());
1391 HMathFloorOfDiv* hdiv = instr->hydrogen();
1394 DeoptimizeIf(zero, instr->environment());
1408 Register temp = ToRegister(instr->temp3());
1426 void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) {
1427 HBinaryOperation* hdiv = instr->hydrogen();
1428 Register dividend = ToRegister(instr->dividend());
1429 Register divisor = ToRegister(instr->divisor());
1430 Register remainder = ToRegister(instr->temp());
1431 Register result = ToRegister(instr->result());
1441 DeoptimizeIf(zero, instr->environment());
1450 DeoptimizeIf(sign, instr->environment());
1460 DeoptimizeIf(zero, instr->environment());
1478 void LCodeGen::DoMulI(LMulI* instr) {
1479 Register left = ToRegister(instr->left());
1480 LOperand* right = instr->right();
1482 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1483 __ mov(ToRegister(instr->temp()), left);
1497 } else if (!instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1531 if (instr->hydrogen()->representation().IsSmi()) {
1537 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1538 DeoptimizeIf(overflow, instr->environment());
1541 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1548 DeoptimizeIf(no_condition, instr->environment());
1550 __ cmp(ToRegister(instr->temp()), Immediate(0));
1551 DeoptimizeIf(less, instr->environment());
1555 __ or_(ToRegister(instr->temp()), ToOperand(right));
1556 DeoptimizeIf(sign, instr->environment());
1563 void LCodeGen::DoBitI(LBitI* instr) {
1564 LOperand* left = instr->left();
1565 LOperand* right = instr->right();
1566 ASSERT(left->Equals(instr->result()));
1572 instr->hydrogen()->representation());
1573 switch (instr->op()) {
1592 switch (instr->op()) {
1610 void LCodeGen::DoShiftI(LShiftI* instr) {
1611 LOperand* left = instr->left();
1612 LOperand* right = instr->right();
1613 ASSERT(left->Equals(instr->result()));
1618 switch (instr->op()) {
1621 if (instr->can_deopt()) {
1623 DeoptimizeIf(sign, instr->environment());
1631 if (instr->can_deopt()) {
1633 DeoptimizeIf(sign, instr->environment());
1646 switch (instr->op()) {
1648 if (shift_count == 0 && instr->can_deopt()) {
1650 DeoptimizeIf(sign, instr->environment());
1663 } else if (instr->can_deopt()) {
1665 DeoptimizeIf(sign, instr->environment());
1670 if (instr->hydrogen_value()->representation().IsSmi() &&
1671 instr->can_deopt()) {
1676 DeoptimizeIf(overflow, instr->environment());
1690 void LCodeGen::DoSubI(LSubI* instr) {
1691 LOperand* left = instr->left();
1692 LOperand* right = instr->right();
1693 ASSERT(left->Equals(instr->result()));
1697 ToImmediate(right, instr->hydrogen()->representation()));
1701 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1702 DeoptimizeIf(overflow, instr->environment());
1707 void LCodeGen::DoConstantI(LConstantI* instr) {
1708 __ Move(ToRegister(instr->result()), Immediate(instr->value()));
1712 void LCodeGen::DoConstantS(LConstantS* instr) {
1713 __ Move(ToRegister(instr->result()), Immediate(instr->value()));
1717 void LCodeGen::DoConstantD(LConstantD* instr) {
1718 double v = instr->value();
1722 ASSERT(instr->result()->IsDoubleRegister());
1724 XMMRegister res = ToDoubleRegister(instr->result());
1728 Register temp = ToRegister(instr->temp());
1756 void LCodeGen::DoConstantE(LConstantE* instr) {
1757 __ lea(ToRegister(instr->result()), Operand::StaticVariable(instr->value()));
1761 void LCodeGen::DoConstantT(LConstantT* instr) {
1762 Register reg = ToRegister(instr->result());
1763 Handle<Object> object = instr->value(isolate());
1769 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1770 Register result = ToRegister(instr->result());
1771 Register map = ToRegister(instr->value());
1776 void LCodeGen::DoDateField(LDateField* instr) {
1777 Register object = ToRegister(instr->date());
1778 Register result = ToRegister(instr->result());
1779 Register scratch = ToRegister(instr->temp());
1780 Smi* index = instr->index();
1786 DeoptimizeIf(zero, instr->environment());
1788 DeoptimizeIf(not_equal, instr->environment());
1831 void LCodeGen::DoSeqStringGetChar(LSeqStringGetChar* instr) {
1832 String::Encoding encoding = instr->hydrogen()->encoding();
1833 Register result = ToRegister(instr->result());
1834 Register string = ToRegister(instr->string());
1850 Operand operand = BuildSeqStringOperand(string, instr->index(), encoding);
1859 void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
1860 String::Encoding encoding = instr->hydrogen()->encoding();
1861 Register string = ToRegister(instr->string());
1864 Register value = ToRegister(instr->value());
1865 Register index = ToRegister(instr->index());
1869 instr->hydrogen()->encoding() == String::ONE_BYTE_ENCODING
1874 Operand operand = BuildSeqStringOperand(string, instr->index(), encoding);
1875 if (instr->value()->IsConstantOperand()) {
1876 int value = ToRepresentation(LConstantOperand::cast(instr->value()),
1887 Register value = ToRegister(instr->value());
1897 void LCodeGen::DoAddI(LAddI* instr) {
1898 LOperand* left = instr->left();
1899 LOperand* right = instr->right();
1901 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) {
1904 instr->hydrogen()->representation());
1905 __ lea(ToRegister(instr->result()), MemOperand(ToRegister(left), offset));
1908 __ lea(ToRegister(instr->result()), address);
1913 ToImmediate(right, instr->hydrogen()->representation()));
1917 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1918 DeoptimizeIf(overflow, instr->environment());
1924 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
1925 LOperand* left = instr->left();
1926 LOperand* right = instr->right();
1927 ASSERT(left->Equals(instr->result()));
1928 HMathMinMax::Operation operation = instr->hydrogen()->operation();
1929 if (instr->hydrogen()->representation().IsSmiOrInteger32()) {
1936 Immediate immediate = ToImmediate(LConstantOperand::cast(instr->right()),
1937 instr->hydrogen()->representation());
1950 ASSERT(instr->hydrogen()->representation().IsDouble());
1986 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1987 XMMRegister left = ToDoubleRegister(instr->left());
1988 XMMRegister right = ToDoubleRegister(instr->right());
1989 XMMRegister result = ToDoubleRegister(instr->result());
1990 switch (instr->op()) {
2030 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
2031 ASSERT(ToRegister(instr->context()).is(esi));
2032 ASSERT(ToRegister(instr->left()).is(edx));
2033 ASSERT(ToRegister(instr->right()).is(eax));
2034 ASSERT(ToRegister(instr->result()).is(eax));
2036 BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE);
2037 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2042 void LCodeGen::EmitBranch(InstrType instr, Condition cc) {
2043 int left_block = instr->TrueDestination(chunk_);
2044 int right_block = instr->FalseDestination(chunk_);
2062 void LCodeGen::EmitFalseBranch(InstrType instr, Condition cc) {
2063 int false_block = instr->FalseDestination(chunk_);
2072 void LCodeGen::DoBranch(LBranch* instr) {
2073 Representation r = instr->hydrogen()->value()->representation();
2075 Register reg = ToRegister(instr->value());
2077 EmitBranch(instr, not_zero);
2080 XMMRegister reg = ToDoubleRegister(instr->value());
2084 EmitBranch(instr, not_equal);
2087 Register reg = ToRegister(instr->value());
2088 HType type = instr->hydrogen()->value()->type();
2092 EmitBranch(instr, equal);
2096 EmitBranch(instr, not_equal);
2099 EmitBranch(instr, no_condition);
2105 EmitBranch(instr, not_equal);
2109 EmitBranch(instr, not_equal);
2111 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
2117 __ j(equal, instr->FalseLabel(chunk_));
2122 __ j(equal, instr->TrueLabel(chunk_));
2125 __ j(equal, instr->FalseLabel(chunk_));
2130 __ j(equal, instr->FalseLabel(chunk_));
2136 __ j(equal, instr->FalseLabel(chunk_));
2137 __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
2141 DeoptimizeIf(zero, instr->environment());
2146 map = ToRegister(instr->temp());
2154 __ j(not_zero, instr->FalseLabel(chunk_));
2161 __ j(above_equal, instr->TrueLabel(chunk_));
2170 __ j(not_zero, instr->TrueLabel(chunk_));
2171 __ jmp(instr->FalseLabel(chunk_));
2178 __ j(equal, instr->TrueLabel(chunk_));
2190 __ j(zero, instr->FalseLabel(chunk_));
2191 __ jmp(instr->TrueLabel(chunk_));
2198 DeoptimizeIf(no_condition, instr->environment());
2212 void LCodeGen::DoGoto(LGoto* instr) {
2213 EmitGoto(instr->block_id());
2249 void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) {
2250 LOperand* left = instr->left();
2251 LOperand* right = instr->right();
2253 instr->is_double() ||
2254 instr->hydrogen()->left()->CheckFlag(HInstruction::kUint32) ||
2255 instr->hydrogen()->right()->CheckFlag(HInstruction::kUint32);
2256 Condition cc = TokenToCondition(instr->op(), is_unsigned);
2262 int next_block = EvalComparison(instr->op(), left_val, right_val) ?
2263 instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_);
2266 if (instr->is_double()) {
2270 __ j(parity_even, instr->FalseLabel(chunk_));
2274 ToImmediate(right, instr->hydrogen()->representation()));
2277 ToImmediate(left, instr->hydrogen()->representation()));
2284 EmitBranch(instr, cc);
2289 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
2290 Register left = ToRegister(instr->left());
2292 if (instr->right()->IsConstantOperand()) {
2293 Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right()));
2296 Operand right = ToOperand(instr->right());
2299 EmitBranch(instr, equal);
2303 void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
2304 if (instr->hydrogen()->representation().IsTagged()) {
2305 Register input_reg = ToRegister(instr->object());
2307 EmitBranch(instr, equal);
2311 XMMRegister input_reg = ToDoubleRegister(instr->object());
2313 EmitFalseBranch(instr, parity_odd);
2321 EmitBranch(instr, equal);
2325 void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
2326 Representation rep = instr->hydrogen()->value()->representation();
2328 Register scratch = ToRegister(instr->temp());
2331 XMMRegister value = ToDoubleRegister(instr->value());
2335 EmitFalseBranch(instr, not_equal);
2338 EmitBranch(instr, not_zero);
2340 Register value = ToRegister(instr->value());
2342 __ CheckMap(value, map, instr->FalseLabel(chunk()), DO_SMI_CHECK);
2345 EmitFalseBranch(instr, no_overflow);
2348 EmitBranch(instr, equal);
2376 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
2377 Register reg = ToRegister(instr->value());
2378 Register temp = ToRegister(instr->temp());
2381 reg, temp, instr->FalseLabel(chunk_), instr->TrueLabel(chunk_));
2383 EmitBranch(instr, true_cond);
2401 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
2402 Register reg = ToRegister(instr->value());
2403 Register temp = ToRegister(instr->temp());
2406 instr->hydrogen()->value()->type().IsHeapObject()
2410 reg, temp, instr->FalseLabel(chunk_), check_needed);
2412 EmitBranch(instr, true_cond);
2416 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
2417 Operand input = ToOperand(instr->value());
2420 EmitBranch(instr, zero);
2424 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
2425 Register input = ToRegister(instr->value());
2426 Register temp = ToRegister(instr->temp());
2428 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
2430 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2435 EmitBranch(instr, not_zero);
2459 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
2460 Token::Value op = instr->op();
2463 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2468 EmitBranch(instr, condition);
2472 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
2473 InstanceType from = instr->from();
2474 InstanceType to = instr->to();
2481 static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
2482 InstanceType from = instr->from();
2483 InstanceType to = instr->to();
2492 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
2493 Register input = ToRegister(instr->value());
2494 Register temp = ToRegister(instr->temp());
2496 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
2497 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2500 __ CmpObjectType(input, TestType(instr->hydrogen()), temp);
2501 EmitBranch(instr, BranchCondition(instr->hydrogen()));
2505 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
2506 Register input = ToRegister(instr->value());
2507 Register result = ToRegister(instr->result());
2517 LHasCachedArrayIndexAndBranch* instr) {
2518 Register input = ToRegister(instr->value());
2522 EmitBranch(instr, equal);
2591 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2592 Register input = ToRegister(instr->value());
2593 Register temp = ToRegister(instr->temp());
2594 Register temp2 = ToRegister(instr->temp2());
2596 Handle<String> class_name = instr->hydrogen()->class_name();
2598 EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
2601 EmitBranch(instr, equal);
2605 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
2606 Register reg = ToRegister(instr->value());
2607 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map());
2608 EmitBranch(instr, equal);
2612 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
2614 ASSERT(ToRegister(instr->context()).is(esi));
2616 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2621 __ mov(ToRegister(instr->result()), factory()->false_value());
2624 __ mov(ToRegister(instr->result()), factory()->true_value());
2629 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
2633 LInstanceOfKnownGlobal* instr)
2634 : LDeferredCode(codegen), instr_(instr) { }
2638 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
2646 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
2649 Register object = ToRegister(instr->value());
2650 Register temp = ToRegister(instr->temp());
2659 Register map = ToRegister(instr->temp());
2683 __ mov(ToRegister(instr->result()), factory()->false_value());
2692 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
2709 Register temp = ToRegister(instr->temp());
2711 __ LoadHeapObject(InstanceofStub::right(), instr->function());
2718 instr,
2722 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment();
2730 void LCodeGen::DoCmpT(LCmpT* instr) {
2731 Token::Value op = instr->op();
2734 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2740 __ mov(ToRegister(instr->result()), factory()->false_value());
2743 __ mov(ToRegister(instr->result()), factory()->true_value());
2748 void LCodeGen::EmitReturn(LReturn* instr, bool dynamic_frame_alignment) {
2751 if (instr->has_constant_parameter_count()) {
2752 int parameter_count = ToInteger32(instr->constant_parameter_count());
2761 Register reg = ToRegister(instr->parameter_count());
2773 // emit code to restore stack based on instr->parameter_count()
2785 void LCodeGen::DoReturn(LReturn* instr) {
2812 EmitReturn(instr, true);
2816 EmitReturn(instr, false);
2823 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
2824 Register result = ToRegister(instr->result());
2825 __ mov(result, Operand::ForCell(instr->hydrogen()->cell().handle()));
2826 if (instr->hydrogen()->RequiresHoleCheck()) {
2828 DeoptimizeIf(equal, instr->environment());
2833 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
2834 ASSERT(ToRegister(instr->context()).is(esi));
2835 ASSERT(ToRegister(instr->global_object()).is(edx));
2836 ASSERT(ToRegister(instr->result()).is(eax));
2838 __ mov(ecx, instr->name());
2839 ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
2841 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2845 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
2846 Register value = ToRegister(instr->value());
2847 Handle<PropertyCell> cell_handle = instr->hydrogen()->cell().handle();
2853 if (instr->hydrogen()->RequiresHoleCheck()) {
2855 DeoptimizeIf(equal, instr->environment());
2864 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
2865 Register context = ToRegister(instr->context());
2866 Register result = ToRegister(instr->result());
2867 __ mov(result, ContextOperand(context, instr->slot_index()));
2869 if (instr->hydrogen()->RequiresHoleCheck()) {
2871 if (instr->hydrogen()->DeoptimizesOnHole()) {
2872 DeoptimizeIf(equal, instr->environment());
2883 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
2884 Register context = ToRegister(instr->context());
2885 Register value = ToRegister(instr->value());
2889 Operand target = ContextOperand(context, instr->slot_index());
2890 if (instr->hydrogen()->RequiresHoleCheck()) {
2892 if (instr->hydrogen()->DeoptimizesOnHole()) {
2893 DeoptimizeIf(equal, instr->environment());
2900 if (instr->hydrogen()->NeedsWriteBarrier()) {
2902 instr->hydrogen()->value()->type().IsHeapObject()
2904 Register temp = ToRegister(instr->temp());
2905 int offset = Context::SlotOffset(instr->slot_index());
2919 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
2920 HObjectAccess access = instr->hydrogen()->access();
2924 Register result = ToRegister(instr->result());
2925 MemOperand operand = instr->object()->IsConstantOperand()
2927 LConstantOperand::cast(instr->object())))
2928 : MemOperand(ToRegister(instr->object()), offset);
2933 Register object = ToRegister(instr->object());
2934 if (instr->hydrogen()->representation().IsDouble()) {
2935 XMMRegister result = ToDoubleRegister(instr->result());
2940 Register result = ToRegister(instr->result());
2967 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
2968 ASSERT(ToRegister(instr->context()).is(esi));
2969 ASSERT(ToRegister(instr->object()).is(edx));
2970 ASSERT(ToRegister(instr->result()).is(eax));
2972 __ mov(ecx, instr->name());
2974 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2978 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
2979 Register function = ToRegister(instr->function());
2980 Register temp = ToRegister(instr->temp());
2981 Register result = ToRegister(instr->result());
2985 DeoptimizeIf(not_equal, instr->environment());
2999 DeoptimizeIf(equal, instr->environment());
3020 void LCodeGen::DoLoadRoot(LLoadRoot* instr) {
3021 Register result = ToRegister(instr->result());
3022 __ LoadRoot(result, instr->index());
3026 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
3027 Register arguments = ToRegister(instr->arguments());
3028 Register result = ToRegister(instr->result());
3029 if (instr->length()->IsConstantOperand() &&
3030 instr->index()->IsConstantOperand()) {
3031 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3032 int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
3036 Register length = ToRegister(instr->length());
3037 Operand index = ToOperand(instr->index());
3046 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
3047 ElementsKind elements_kind = instr->elements_kind();
3048 LOperand* key = instr->key();
3050 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(),
3055 instr->elements(),
3057 instr->hydrogen()->key()->representation(),
3059 instr->base_offset()));
3062 XMMRegister result(ToDoubleRegister(instr->result()));
3067 __ movsd(ToDoubleRegister(instr->result()), operand);
3069 Register result(ToRegister(instr->result()));
3096 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
3098 DeoptimizeIf(negative, instr->environment());
3120 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
3121 if (instr->hydrogen()->RequiresHoleCheck()) {
3123 instr->elements(), instr->key(),
3124 instr->hydrogen()->key()->representation(),
3126 instr->base_offset() + sizeof(kHoleNanLower32));
3128 DeoptimizeIf(equal, instr->environment());
3132 instr->elements(),
3133 instr->key(),
3134 instr->hydrogen()->key()->representation(),
3136 instr->base_offset());
3137 XMMRegister result = ToDoubleRegister(instr->result());
3142 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3143 Register result = ToRegister(instr->result());
3147 BuildFastArrayOperand(instr->elements(),
3148 instr->key(),
3149 instr->hydrogen()->key()->representation(),
3151 instr->base_offset()));
3154 if (instr->hydrogen()->RequiresHoleCheck()) {
3155 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
3157 DeoptimizeIf(not_equal, instr->environment());
3160 DeoptimizeIf(equal, instr->environment());
3166 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
3167 if (instr->is_typed_elements()) {
3168 DoLoadKeyedExternalArray(instr);
3169 } else if (instr->hydrogen()->representation().IsDouble()) {
3170 DoLoadKeyedFixedDoubleArray(instr);
3172 DoLoadKeyedFixedArray(instr);
3208 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
3209 ASSERT(ToRegister(instr->context()).is(esi));
3210 ASSERT(ToRegister(instr->object()).is(edx));
3211 ASSERT(ToRegister(instr->key()).is(ecx));
3214 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3218 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
3219 Register result = ToRegister(instr->result());
3221 if (instr->hydrogen()->from_inlined()) {
3247 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
3248 Operand elem = ToOperand(instr->elements());
3249 Register result = ToRegister(instr->result());
3269 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
3270 Register receiver = ToRegister(instr->receiver());
3271 Register function = ToRegister(instr->function());
3278 Register scratch = ToRegister(instr->temp());
3280 if (!instr->hydrogen()->known_function()) {
3303 DeoptimizeIf(equal, instr->environment());
3305 DeoptimizeIf(below, instr->environment());
3318 void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
3319 Register receiver = ToRegister(instr->receiver());
3320 Register function = ToRegister(instr->function());
3321 Register length = ToRegister(instr->length());
3322 Register elements = ToRegister(instr->elements());
3325 ASSERT(ToRegister(instr->result()).is(eax));
3331 DeoptimizeIf(above, instr->environment());
3349 ASSERT(instr->HasPointerMap());
3350 LPointerMap* pointers = instr->pointer_map();
3358 void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
3363 void LCodeGen::DoPushArgument(LPushArgument* instr) {
3364 LOperand* argument = instr->value();
3369 void LCodeGen::DoDrop(LDrop* instr) {
3370 __ Drop(instr->count());
3374 void LCodeGen::DoThisFunction(LThisFunction* instr) {
3375 Register result = ToRegister(instr->result());
3380 void LCodeGen::DoContext(LContext* instr) {
3381 Register result = ToRegister(instr->result());
3391 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
3392 ASSERT(ToRegister(instr->context()).is(esi));
3394 __ push(Immediate(instr->hydrogen()->pairs()));
3395 __ push(Immediate(Smi::FromInt(instr->hydrogen()->flags())));
3396 CallRuntime(Runtime::kHiddenDeclareGlobals, 3, instr);
3403 LInstruction* instr,
3430 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
3433 LPointerMap* pointers = instr->pointer_map();
3443 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
3444 ASSERT(ToRegister(instr->result()).is(eax));
3446 LPointerMap* pointers = instr->pointer_map();
3449 if (instr->target()->IsConstantOperand()) {
3450 LConstantOperand* target = LConstantOperand::cast(instr->target());
3455 ASSERT(instr->target()->IsRegister());
3456 Register target = ToRegister(instr->target());
3465 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) {
3466 ASSERT(ToRegister(instr->function()).is(edi));
3467 ASSERT(ToRegister(instr->result()).is(eax));
3469 if (instr->hydrogen()->pass_argument_count()) {
3470 __ mov(eax, instr->arity());
3477 if (instr->hydrogen()->function()->IsConstant()) {
3478 HConstant* fun_const = HConstant::cast(instr->hydrogen()->function());
3490 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
3494 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3495 Register input_reg = ToRegister(instr->value());
3498 DeoptimizeIf(not_equal, instr->environment());
3521 instr, instr->context());
3539 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
3540 Register input_reg = ToRegister(instr->value());
3545 DeoptimizeIf(negative, instr->environment());
3550 void LCodeGen::DoMathAbs(LMathAbs* instr) {
3555 LMathAbs* instr)
3556 : LDeferredCode(codegen), instr_(instr) { }
3560 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
3565 ASSERT(instr->value()->Equals(instr->result()));
3566 Representation r = instr->hydrogen()->value()->representation();
3570 XMMRegister input_reg = ToDoubleRegister(instr->value());
3575 EmitIntegerMathAbs(instr);
3578 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
3579 Register input_reg = ToRegister(instr->value());
3582 EmitIntegerMathAbs(instr);
3588 void LCodeGen::DoMathFloor(LMathFloor* instr) {
3590 Register output_reg = ToRegister(instr->result());
3591 XMMRegister input_reg = ToDoubleRegister(instr->value());
3595 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3603 DeoptimizeIf(not_zero, instr->environment());
3610 DeoptimizeIf(overflow, instr->environment());
3616 DeoptimizeIf(parity_even, instr->environment());
3619 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3625 DeoptimizeIf(not_zero, instr->environment());
3635 DeoptimizeIf(overflow, instr->environment());
3646 DeoptimizeIf(overflow, instr->environment());
3653 void LCodeGen::DoMathRound(LMathRound* instr) {
3654 Register output_reg = ToRegister(instr->result());
3655 XMMRegister input_reg = ToDoubleRegister(instr->value());
3657 XMMRegister input_temp = ToDoubleRegister(instr->temp());
3675 DeoptimizeIf(overflow, instr->environment());
3691 DeoptimizeIf(overflow, instr->environment());
3703 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3708 DeoptimizeIf(not_zero, instr->environment());
3715 void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
3716 Operand input = ToOperand(instr->value());
3717 XMMRegister output = ToDoubleRegister(instr->result());
3722 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
3724 XMMRegister input_reg = ToDoubleRegister(instr->value());
3725 Register scratch = ToRegister(instr->temp());
3726 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
3756 void LCodeGen::DoPower(LPower* instr) {
3757 Representation exponent_type = instr->hydrogen()->right()->representation();
3760 ASSERT(!instr->right()->IsDoubleRegister() ||
3761 ToDoubleRegister(instr->right()).is(xmm1));
3762 ASSERT(!instr->right()->IsRegister() ||
3763 ToRegister(instr->right()).is(eax));
3764 ASSERT(ToDoubleRegister(instr->left()).is(xmm2));
3765 ASSERT(ToDoubleRegister(instr->result()).is(xmm3));
3774 DeoptimizeIf(not_equal, instr->environment());
3789 void LCodeGen::DoMathLog(LMathLog* instr) {
3790 ASSERT(instr->value()->Equals(instr->result()));
3791 XMMRegister input_reg = ToDoubleRegister(instr->value());
3820 void LCodeGen::DoMathClz32(LMathClz32* instr) {
3821 Register input = ToRegister(instr->value());
3822 Register result = ToRegister(instr->result());
3834 void LCodeGen::DoMathExp(LMathExp* instr) {
3835 XMMRegister input = ToDoubleRegister(instr->value());
3836 XMMRegister result = ToDoubleRegister(instr->result());
3838 Register temp1 = ToRegister(instr->temp1());
3839 Register temp2 = ToRegister(instr->temp2());
3845 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
3846 ASSERT(ToRegister(instr->context()).is(esi));
3847 ASSERT(ToRegister(instr->function()).is(edi));
3848 ASSERT(instr->HasPointerMap());
3850 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
3852 LPointerMap* pointers = instr->pointer_map();
3855 ParameterCount count(instr->arity());
3859 instr->hydrogen()->formal_parameter_count(),
3860 instr->arity(),
3861 instr,
3867 void LCodeGen::DoCallFunction(LCallFunction* instr) {
3868 ASSERT(ToRegister(instr->context()).is(esi));
3869 ASSERT(ToRegister(instr->function()).is(edi));
3870 ASSERT(ToRegister(instr->result()).is(eax));
3872 int arity = instr->arity();
3873 CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
3874 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
3878 void LCodeGen::DoCallNew(LCallNew* instr) {
3879 ASSERT(ToRegister(instr->context()).is(esi));
3880 ASSERT(ToRegister(instr->constructor()).is(edi));
3881 ASSERT(ToRegister(instr->result()).is(eax));
3886 __ Move(eax, Immediate(instr->arity()));
3887 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
3891 void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
3892 ASSERT(ToRegister(instr->context()).is(esi));
3893 ASSERT(ToRegister(instr->constructor()).is(edi));
3894 ASSERT(ToRegister(instr->result()).is(eax));
3896 __ Move(eax, Immediate(instr->arity()));
3898 ElementsKind kind = instr->hydrogen()->elements_kind();
3904 if (instr->arity() == 0) {
3906 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
3907 } else if (instr->arity() == 1) {
3921 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
3927 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
3931 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
3936 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
3937 ASSERT(ToRegister(instr->context()).is(esi));
3938 CallRuntime(instr->function(), instr->arity(), instr, instr->save_doubles());
3942 void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) {
3943 Register function = ToRegister(instr->function());
3944 Register code_object = ToRegister(instr->code_object());
3950 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
3951 Register result = ToRegister(instr->result());
3952 Register base = ToRegister(instr->base_object());
3953 if (instr->offset()->IsConstantOperand()) {
3954 LConstantOperand* offset = LConstantOperand::cast(instr->offset());
3957 Register offset = ToRegister(instr->offset());
3963 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
3964 Representation representation = instr->hydrogen()->field_representation();
3966 HObjectAccess access = instr->hydrogen()->access();
3970 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
3971 MemOperand operand = instr->object()->IsConstantOperand()
3973 ToExternalReference(LConstantOperand::cast(instr->object())))
3974 : MemOperand(ToRegister(instr->object()), offset);
3975 if (instr->value()->IsConstantOperand()) {
3976 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
3979 Register value = ToRegister(instr->value());
3985 Register object = ToRegister(instr->object());
3989 !instr->value()->IsConstantOperand() ||
3990 IsSmi(LConstantOperand::cast(instr->value())));
3993 ASSERT(!instr->hydrogen()->has_transition());
3994 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
3995 XMMRegister value = ToDoubleRegister(instr->value());
4000 if (instr->hydrogen()->has_transition()) {
4001 Handle<Map> transition = instr->hydrogen()->transition_map();
4004 if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
4005 Register temp = ToRegister(instr->temp());
4006 Register temp_map = ToRegister(instr->temp_map());
4015 write_register = ToRegister(instr->temp());
4020 if (instr->value()->IsConstantOperand()) {
4021 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4027 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4031 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4035 Register value = ToRegister(instr->value());
4039 if (instr->hydrogen()->NeedsWriteBarrier()) {
4040 Register value = ToRegister(instr->value());
4041 Register temp = access.IsInobject() ? ToRegister(instr->temp()) : object;
4049 instr->hydrogen()->SmiCheckForWriteBarrier(),
4050 instr->hydrogen()->PointersToHereCheckForValue());
4055 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
4056 ASSERT(ToRegister(instr->context()).is(esi));
4057 ASSERT(ToRegister(instr->object()).is(edx));
4058 ASSERT(ToRegister(instr->value()).is(eax));
4060 __ mov(ecx, instr->name());
4061 Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode());
4062 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4066 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
4067 Condition cc = instr->hydrogen()->allow_equality() ? above : above_equal;
4068 if (instr->index()->IsConstantOperand()) {
4069 __ cmp(ToOperand(instr->length()),
4070 ToImmediate(LConstantOperand::cast(instr->index()),
4071 instr->hydrogen()->length()->representation()));
4073 } else if (instr->length()->IsConstantOperand()) {
4074 __ cmp(ToOperand(instr->index()),
4075 ToImmediate(LConstantOperand::cast(instr->length()),
4076 instr->hydrogen()->index()->representation()));
4078 __ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
4080 if (FLAG_debug_code && instr->hydrogen()->skip_check()) {
4086 DeoptimizeIf(cc, instr->environment());
4091 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4092 ElementsKind elements_kind = instr->elements_kind();
4093 LOperand* key = instr->key();
4095 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(),
4100 instr->elements(),
4102 instr->hydrogen()->key()->representation(),
4104 instr->base_offset()));
4108 __ cvtsd2ss(xmm_scratch, ToDoubleRegister(instr->value()));
4112 __ movsd(operand, ToDoubleRegister(instr->value()));
4114 Register value = ToRegister(instr->value());
4155 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
4159 instr->elements(),
4160 instr->key(),
4161 instr->hydrogen()->key()->representation(),
4163 instr->base_offset());
4165 XMMRegister value = ToDoubleRegister(instr->value());
4167 if (instr->NeedsCanonicalization()) {
4181 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4182 Register elements = ToRegister(instr->elements());
4183 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
4186 instr->elements(),
4187 instr->key(),
4188 instr->hydrogen()->key()->representation(),
4190 instr->base_offset());
4191 if (instr->value()->IsRegister()) {
4192 __ mov(operand, ToRegister(instr->value()));
4194 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4205 if (instr->hydrogen()->NeedsWriteBarrier()) {
4206 ASSERT(instr->value()->IsRegister());
4207 Register value = ToRegister(instr->value());
4208 ASSERT(!instr->key()->IsConstantOperand());
4210 instr->hydrogen()->value()->type().IsHeapObject()
4220 instr->hydrogen()->PointersToHereCheckForValue());
4225 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
4227 if (instr->is_typed_elements()) {
4228 DoStoreKeyedExternalArray(instr);
4229 } else if (instr->hydrogen()->value()->representation().IsDouble()) {
4230 DoStoreKeyedFixedDoubleArray(instr);
4232 DoStoreKeyedFixedArray(instr);
4237 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
4238 ASSERT(ToRegister(instr->context()).is(esi));
4239 ASSERT(ToRegister(instr->object()).is(edx));
4240 ASSERT(ToRegister(instr->key()).is(ecx));
4241 ASSERT(ToRegister(instr->value()).is(eax));
4243 Handle<Code> ic = instr->strict_mode() == STRICT
4246 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4250 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
4251 Register object = ToRegister(instr->object());
4252 Register temp = ToRegister(instr->temp());
4255 DeoptimizeIf(equal, instr->environment());
4260 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
4261 Register object_reg = ToRegister(instr->object());
4263 Handle<Map> from_map = instr->original_map();
4264 Handle<Map> to_map = instr->transitioned_map();
4265 ElementsKind from_kind = instr->from_kind();
4266 ElementsKind to_kind = instr->to_kind();
4276 Register new_map_reg = ToRegister(instr->new_map_temp());
4280 ASSERT_NE(instr->temp(), NULL);
4282 ToRegister(instr->temp()),
4285 ASSERT(ToRegister(instr->context()).is(esi));
4292 RecordSafepointWithLazyDeopt(instr,
4299 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
4303 LStringCharCodeAt* instr)
4304 : LDeferredCode(codegen), instr_(instr) { }
4308 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4314 new(zone()) DeferredStringCharCodeAt(this, instr);
4318 ToRegister(instr->string()),
4319 ToRegister(instr->index()),
4320 ToRegister(instr->result()),
4326 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
4327 Register string = ToRegister(instr->string());
4328 Register result = ToRegister(instr->result());
4340 if (instr->index()->IsConstantOperand()) {
4341 Immediate immediate = ToImmediate(LConstantOperand::cast(instr->index()),
4345 Register index = ToRegister(instr->index());
4350 instr, instr->context());
4357 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
4361 LStringCharFromCode* instr)
4362 : LDeferredCode(codegen), instr_(instr) { }
4366 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4372 instr);
4374 ASSERT(instr->hydrogen()->value()->representation().IsInteger32());
4375 Register char_code = ToRegister(instr->char_code());
4376 Register result = ToRegister(instr->result());
4391 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
4392 Register char_code = ToRegister(instr->char_code());
4393 Register result = ToRegister(instr->result());
4403 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context());
4408 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4409 ASSERT(ToRegister(instr->context()).is(esi));
4410 ASSERT(ToRegister(instr->left()).is(edx));
4411 ASSERT(ToRegister(instr->right()).is(eax));
4413 instr->hydrogen()->flags(),
4414 instr->hydrogen()->pretenure_flag());
4415 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
4419 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4420 LOperand* input = instr->value();
4421 LOperand* output = instr->result();
4428 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4429 LOperand* input = instr->value();
4430 LOperand* output = instr->result();
4435 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4439 LNumberTagI* instr)
4440 : LDeferredCode(codegen), instr_(instr) { }
4445 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4450 LOperand* input = instr->value();
4451 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4455 new(zone()) DeferredNumberTagI(this, instr);
4462 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4465 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
4466 : LDeferredCode(codegen), instr_(instr) { }
4471 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4476 LOperand* input = instr->value();
4477 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4481 new(zone()) DeferredNumberTagU(this, instr);
4489 void LCodeGen::DoDeferredNumberTagIU(LInstruction* instr,
4533 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4544 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
4547 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4548 : LDeferredCode(codegen), instr_(instr) { }
4552 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4557 Register reg = ToRegister(instr->result());
4560 new(zone()) DeferredNumberTagD(this, instr);
4562 Register tmp = ToRegister(instr->temp());
4568 XMMRegister input_reg = ToDoubleRegister(instr->value());
4573 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
4577 Register reg = ToRegister(instr->result());
4589 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4594 void LCodeGen::DoSmiTag(LSmiTag* instr) {
4595 HChange* hchange = instr->hydrogen();
4596 Register input = ToRegister(instr->value());
4600 DeoptimizeIf(not_zero, instr->environment());
4605 DeoptimizeIf(overflow, instr->environment());
4610 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
4611 LOperand* input = instr->value();
4613 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4614 if (instr->needs_check()) {
4616 DeoptimizeIf(not_zero, instr->environment());
4686 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) {
4687 Register input_reg = ToRegister(instr->value());
4693 if (instr->truncating()) {
4720 DeoptimizeIf(not_equal, instr->environment());
4724 XMMRegister scratch = (instr->temp() != NULL)
4725 ? ToDoubleRegister(instr->temp())
4728 instr->hydrogen()->GetMinusZeroMode(), &bailout);
4731 DeoptimizeIf(no_condition, instr->environment());
4736 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
4739 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
4740 : LDeferredCode(codegen), instr_(instr) { }
4744 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4749 LOperand* input = instr->value();
4752 ASSERT(input_reg.is(ToRegister(instr->result())));
4754 if (instr->hydrogen()->value()->representation().IsSmi()) {
4758 new(zone()) DeferredTaggedToI(this, instr);
4771 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
4772 LOperand* input = instr->value();
4774 LOperand* temp = instr->temp();
4776 LOperand* result = instr->result();
4781 instr->hydrogen()->deoptimize_on_minus_zero();
4784 HValue* value = instr->hydrogen()->value();
4792 instr->hydrogen()->can_convert_undefined_to_nan(),
4794 instr->environment(),
4799 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
4800 LOperand* input = instr->value();
4802 LOperand* result = instr->result();
4806 if (instr->truncating()) {
4814 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);
4817 DeoptimizeIf(no_condition, instr->environment());
4823 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
4824 LOperand* input = instr->value();
4826 LOperand* result = instr->result();
4834 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);
4837 DeoptimizeIf(no_condition, instr->environment());
4841 DeoptimizeIf(overflow, instr->environment());
4845 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
4846 LOperand* input = instr->value();
4848 DeoptimizeIf(not_zero, instr->environment());
4852 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
4853 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
4854 LOperand* input = instr->value();
4856 instr->environment());
4861 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
4862 Register input = ToRegister(instr->value());
4863 Register temp = ToRegister(instr->temp());
4867 if (instr->hydrogen()->is_interval_check()) {
4870 instr->hydrogen()->GetCheckInterval(&first, &last);
4877 DeoptimizeIf(not_equal, instr->environment());
4879 DeoptimizeIf(below, instr->environment());
4884 DeoptimizeIf(above, instr->environment());
4890 instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
4895 DeoptimizeIf(tag == 0 ? not_zero : zero, instr->environment());
4900 DeoptimizeIf(not_equal, instr->environment());
4906 void LCodeGen::DoCheckValue(LCheckValue* instr) {
4907 Handle<HeapObject> object = instr->hydrogen()->object().handle();
4908 if (instr->hydrogen()->object_in_new_space()) {
4909 Register reg = ToRegister(instr->value());
4913 Operand operand = ToOperand(instr->value());
4916 DeoptimizeIf(not_equal, instr->environment());
4920 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
4927 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt);
4931 DeoptimizeIf(zero, instr->environment());
4935 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
4938 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object)
4939 : LDeferredCode(codegen), instr_(instr), object_(object) {
4946 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4953 if (instr->hydrogen()->IsStabilityCheck()) {
4954 const UniqueSet<Map>* maps = instr->hydrogen()->maps();
4961 LOperand* input = instr->value();
4966 if (instr->hydrogen()->HasMigrationTarget()) {
4967 deferred = new(zone()) DeferredCheckMaps(this, instr, reg);
4971 const UniqueSet<Map>* maps = instr->hydrogen()->maps();
4981 if (instr->hydrogen()->HasMigrationTarget()) {
4984 DeoptimizeIf(not_equal, instr->environment());
4991 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
4992 XMMRegister value_reg = ToDoubleRegister(instr->unclamped());
4994 Register result_reg = ToRegister(instr->result());
4999 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
5000 ASSERT(instr->unclamped()->Equals(instr->result()));
5001 Register value_reg = ToRegister(instr->result());
5006 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
5007 ASSERT(instr->unclamped()->Equals(instr->result()));
5008 Register input_reg = ToRegister(instr->unclamped());
5009 XMMRegister temp_xmm_reg = ToDoubleRegister(instr->temp_xmm());
5023 DeoptimizeIf(not_equal, instr->environment());
5041 void LCodeGen::DoDoubleBits(LDoubleBits* instr) {
5042 XMMRegister value_reg = ToDoubleRegister(instr->value());
5043 Register result_reg = ToRegister(instr->result());
5044 if (instr->hydrogen()->bits() == HDoubleBits::HIGH) {
5059 void LCodeGen::DoConstructDouble(LConstructDouble* instr) {
5060 Register hi_reg = ToRegister(instr->hi());
5061 Register lo_reg = ToRegister(instr->lo());
5062 XMMRegister result_reg = ToDoubleRegister(instr->result());
5078 void LCodeGen::DoAllocate(LAllocate* instr) {
5081 DeferredAllocate(LCodeGen* codegen, LAllocate* instr)
5082 : LDeferredCode(codegen), instr_(instr) { }
5086 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5091 DeferredAllocate* deferred = new(zone()) DeferredAllocate(this, instr);
5093 Register result = ToRegister(instr->result());
5094 Register temp = ToRegister(instr->temp());
5098 if (instr->hydrogen()->MustAllocateDoubleAligned()) {
5101 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5102 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation());
5103 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5105 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5106 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5110 if (instr->size()->IsConstantOperand()) {
5111 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5118 Register size = ToRegister(instr->size());
5124 if (instr->hydrogen()->MustPrefillWithFiller()) {
5125 if (instr->size()->IsConstantOperand()) {
5126 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5129 temp = ToRegister(instr->size());
5143 void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
5144 Register result = ToRegister(instr->result());
5152 if (instr->size()->IsRegister()) {
5153 Register size = ToRegister(instr->size());
5155 __ SmiTag(ToRegister(instr->size()));
5158 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5169 instr->hydrogen()->MustAllocateDoubleAligned());
5170 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5171 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation());
5172 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5174 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5175 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5183 Runtime::kHiddenAllocateInTargetSpace, 2, instr, instr->context());
5188 void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
5189 ASSERT(ToRegister(instr->value()).is(eax));
5191 CallRuntime(Runtime::kToFastProperties, 1, instr);
5195 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
5196 ASSERT(ToRegister(instr->context()).is(esi));
5204 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
5205 __ LoadHeapObject(ecx, instr->hydrogen()->literals());
5213 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index())));
5214 __ push(Immediate(instr->hydrogen()->pattern()));
5215 __ push(Immediate(instr->hydrogen()->flags()));
5216 CallRuntime(Runtime::kHiddenMaterializeRegExpLiteral, 4, instr);
5228 CallRuntime(Runtime::kHiddenAllocateInNewSpace, 1, instr);
5247 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
5248 ASSERT(ToRegister(instr->context()).is(esi));
5251 bool pretenure = instr->hydrogen()->pretenure();
5252 if (!pretenure && instr->hydrogen()->has_no_literals()) {
5254 instr->hydrogen()->strict_mode(),
5255 instr->hydrogen()->is_generator());
5256 __ mov(ebx, Immediate(instr->hydrogen()->shared_info()));
5257 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
5260 __ push(Immediate(instr->hydrogen()->shared_info()));
5263 CallRuntime(Runtime::kHiddenNewClosure, 3, instr);
5268 void LCodeGen::DoTypeof(LTypeof* instr) {
5269 ASSERT(ToRegister(instr->context()).is(esi));
5270 LOperand* input = instr->value();
5272 CallRuntime(Runtime::kTypeof, 1, instr);
5276 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
5277 Register input = ToRegister(instr->value());
5278 Condition final_branch_condition = EmitTypeofIs(instr, input);
5280 EmitBranch(instr, final_branch_condition);
5285 Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) {
5286 Label* true_label = instr->TrueLabel(chunk_);
5287 Label* false_label = instr->FalseLabel(chunk_);
5288 Handle<String> type_name = instr->type_literal();
5289 int left_block = instr->TrueDestination(chunk_);
5290 int right_block = instr->FalseDestination(chunk_);
5368 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
5369 Register temp = ToRegister(instr->temp());
5372 EmitBranch(instr, equal);
5408 void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
5410 ASSERT(instr->HasEnvironment());
5411 LEnvironment* env = instr->environment();
5417 void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
5418 Deoptimizer::BailoutType type = instr->hydrogen()->type();
5426 Comment(";;; deoptimize: %s", instr->hydrogen()->reason());
5427 DeoptimizeIf(no_condition, instr->environment(), type);
5431 void LCodeGen::DoDummy(LDummy* instr) {
5436 void LCodeGen::DoDummyUse(LDummyUse* instr) {
5441 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
5446 instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
5447 ASSERT(instr->HasEnvironment());
5448 LEnvironment* env = instr->environment();
5453 void LCodeGen::DoStackCheck(LStackCheck* instr) {
5456 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
5457 : LDeferredCode(codegen), instr_(instr) { }
5461 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5466 ASSERT(instr->HasEnvironment());
5467 LEnvironment* env = instr->environment();
5470 if (instr->hydrogen()->is_function_entry()) {
5478 ASSERT(instr->context()->IsRegister());
5479 ASSERT(ToRegister(instr->context()).is(esi));
5482 instr);
5485 ASSERT(instr->hydrogen()->is_backwards_branch());
5488 new(zone()) DeferredStackCheck(this, instr);
5494 __ bind(instr->done_label());
5495 deferred_stack_check->SetExit(instr->done_label());
5504 void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
5508 LEnvironment* environment = instr->environment();
5519 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
5520 ASSERT(ToRegister(instr->context()).is(esi));
5522 DeoptimizeIf(equal, instr->environment());
5525 DeoptimizeIf(equal, instr->environment());
5528 DeoptimizeIf(zero, instr->environment());
5532 DeoptimizeIf(below_equal, instr->environment());
5543 CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr);
5547 DeoptimizeIf(not_equal, instr->environment());
5552 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) {
5553 Register map = ToRegister(instr->map());
5554 Register result = ToRegister(instr->result());
5567 FieldOperand(result, FixedArray::SizeFor(instr->idx())));
5570 DeoptimizeIf(equal, instr->environment());
5574 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
5575 Register object = ToRegister(instr->value());
5576 __ cmp(ToRegister(instr->map()),
5578 DeoptimizeIf(not_equal, instr->environment());
5582 void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
5591 instr->pointer_map(), 2, Safepoint::kNoLazyDeopt);
5596 void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
5600 LLoadFieldByIndex* instr,
5604 instr_(instr),
5611 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5618 Register object = ToRegister(instr->object());
5619 Register index = ToRegister(instr->index());
5623 this, instr, object, index);
5652 void LCodeGen::DoStoreFrameContext(LStoreFrameContext* instr) {
5653 Register context = ToRegister(instr->context());
5658 void LCodeGen::DoAllocateBlockContext(LAllocateBlockContext* instr) {
5659 Handle<ScopeInfo> scope_info = instr->scope_info();
5661 __ push(ToRegister(instr->function()));
5662 CallRuntime(Runtime::kHiddenPushBlockContext, 2, instr);