Home | History | Annotate | Download | only in ia32

Lines Matching refs:instr

384 void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
385 if (!CpuFeatures::IsSupported(SSE2)) FlushX87StackIfNecessary(instr);
389 void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) {
391 if (instr->IsGoto()) {
392 x87_stack_.LeavingBlock(current_block_, LGoto::cast(instr));
394 !instr->IsGap() && !instr->IsReturn()) {
395 if (instr->ClobbersDoubleRegisters()) {
396 if (instr->HasDoubleRegisterResult()) {
476 code->instr()->hydrogen_value()->id(),
477 code->instr()->Mnemonic());
692 void LCodeGen::X87Stack::FlushIfNecessary(LInstruction* instr, LCodeGen* cgen) {
693 if (stack_depth_ > 0 && instr->ClobbersDoubleRegisters()) {
694 bool double_inputs = instr->HasDoubleRegisterInput();
701 if (double_inputs && instr->IsDoubleInput(reg, cgen)) {
708 if (instr->IsReturn()) {
974 LInstruction* instr,
976 ASSERT(instr != NULL);
978 RecordSafepointWithLazyDeopt(instr, safepoint_mode);
991 LInstruction* instr) {
992 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT);
998 LInstruction* instr,
1000 ASSERT(instr != NULL);
1001 ASSERT(instr->HasPointerMap());
1005 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
1029 LInstruction* instr,
1035 instr->pointer_map(), argc, Safepoint::kNoLazyDeopt);
1226 LInstruction* instr, SafepointMode safepoint_mode) {
1228 RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt);
1232 instr->pointer_map(), 0, Safepoint::kLazyDeopt);
1318 void LCodeGen::DoInstructionGap(LInstructionGap* instr) {
1319 DoGap(instr);
1323 void LCodeGen::DoParameter(LParameter* instr) {
1328 void LCodeGen::DoCallStub(LCallStub* instr) {
1329 ASSERT(ToRegister(instr->context()).is(esi));
1330 ASSERT(ToRegister(instr->result()).is(eax));
1331 switch (instr->hydrogen()->major_key()) {
1334 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1339 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1344 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1349 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1353 TranscendentalCacheStub stub(instr->transcendental_type(),
1355 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1364 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
1369 void LCodeGen::DoModI(LModI* instr) {
1370 HMod* hmod = instr->hydrogen();
1376 Register left_reg = ToRegister(instr->left());
1377 ASSERT(left_reg.is(ToRegister(instr->result())));
1390 DeoptimizeIf(zero, instr->environment());
1399 Register left_reg = ToRegister(instr->left());
1401 Register right_reg = ToRegister(instr->right());
1404 Register result_reg = ToRegister(instr->result());
1412 DeoptimizeIf(zero, instr->environment());
1423 DeoptimizeIf(equal, instr->environment());
1444 DeoptimizeIf(zero, instr->environment());
1454 void LCodeGen::DoDivI(LDivI* instr) {
1455 if (!instr->is_flooring() && instr->hydrogen()->HasPowerOf2Divisor()) {
1456 Register dividend = ToRegister(instr->left());
1457 int32_t divisor = instr->hydrogen()->right()->GetInteger32Constant();
1466 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1468 DeoptimizeIf(zero, instr->environment());
1471 if (divisor == -1 && instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1473 DeoptimizeIf(zero, instr->environment());
1480 if (instr->hydrogen()->CheckFlag(
1498 DeoptimizeIf(not_zero, instr->environment());
1508 LOperand* right = instr->right();
1509 ASSERT(ToRegister(instr->result()).is(eax));
1510 ASSERT(ToRegister(instr->left()).is(eax));
1511 ASSERT(!ToRegister(instr->right()).is(eax));
1512 ASSERT(!ToRegister(instr->right()).is(edx));
1518 if (instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) {
1520 DeoptimizeIf(zero, instr->environment());
1524 if (instr->hydrogen_value()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1529 DeoptimizeIf(sign, instr->environment());
1534 if (instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)) {
1539 DeoptimizeIf(zero, instr->environment());
1547 if (instr->is_flooring()) {
1555 } else if (!instr->hydrogen()->CheckFlag(
1559 DeoptimizeIf(not_zero, instr->environment());
1564 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
1565 ASSERT(instr->right()->IsConstantOperand());
1567 Register dividend = ToRegister(instr->left());
1568 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right()));
1569 Register result = ToRegister(instr->result());
1573 DeoptimizeIf(no_condition, instr->environment());
1583 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1584 DeoptimizeIf(zero, instr->environment());
1586 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1587 DeoptimizeIf(overflow, instr->environment());
1601 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1602 DeoptimizeIf(zero, instr->environment());
1614 ASSERT(ToRegister(instr->left()).is(eax));
1615 ASSERT(ToRegister(instr->result()).is(edx));
1616 Register scratch = ToRegister(instr->temp());
1634 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1636 DeoptimizeIf(zero, instr->environment());
1667 void LCodeGen::DoMulI(LMulI* instr) {
1668 Register left = ToRegister(instr->left());
1669 LOperand* right = instr->right();
1671 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1672 __ mov(ToRegister(instr->temp()), left);
1686 } else if (!instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1720 if (instr->hydrogen()->representation().IsSmi()) {
1726 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1727 DeoptimizeIf(overflow, instr->environment());
1730 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1737 DeoptimizeIf(no_condition, instr->environment());
1739 __ cmp(ToRegister(instr->temp()), Immediate(0));
1740 DeoptimizeIf(less, instr->environment());
1744 __ or_(ToRegister(instr->temp()), ToOperand(right));
1745 DeoptimizeIf(sign, instr->environment());
1752 void LCodeGen::DoBitI(LBitI* instr) {
1753 LOperand* left = instr->left();
1754 LOperand* right = instr->right();
1755 ASSERT(left->Equals(instr->result()));
1761 instr->hydrogen()->representation());
1762 switch (instr->op()) {
1781 switch (instr->op()) {
1799 void LCodeGen::DoShiftI(LShiftI* instr) {
1800 LOperand* left = instr->left();
1801 LOperand* right = instr->right();
1802 ASSERT(left->Equals(instr->result()));
1807 switch (instr->op()) {
1810 if (instr->can_deopt()) {
1812 DeoptimizeIf(sign, instr->environment());
1820 if (instr->can_deopt()) {
1822 DeoptimizeIf(sign, instr->environment());
1835 switch (instr->op()) {
1837 if (shift_count == 0 && instr->can_deopt()) {
1839 DeoptimizeIf(sign, instr->environment());
1850 if (shift_count == 0 && instr->can_deopt()) {
1852 DeoptimizeIf(sign, instr->environment());
1859 if (instr->hydrogen_value()->representation().IsSmi() &&
1860 instr->can_deopt()) {
1865 DeoptimizeIf(overflow, instr->environment());
1879 void LCodeGen::DoSubI(LSubI* instr) {
1880 LOperand* left = instr->left();
1881 LOperand* right = instr->right();
1882 ASSERT(left->Equals(instr->result()));
1886 ToImmediate(right, instr->hydrogen()->representation()));
1890 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1891 DeoptimizeIf(overflow, instr->environment());
1896 void LCodeGen::DoConstantI(LConstantI* instr) {
1897 __ Set(ToRegister(instr->result()), Immediate(instr->value()));
1901 void LCodeGen::DoConstantS(LConstantS* instr) {
1902 __ Set(ToRegister(instr->result()), Immediate(instr->value()));
1906 void LCodeGen::DoConstantD(LConstantD* instr) {
1907 double v = instr->value();
1911 ASSERT(instr->result()->IsDoubleRegister());
1916 X87Register reg = ToX87Register(instr->result());
1921 XMMRegister res = ToDoubleRegister(instr->result());
1925 Register temp = ToRegister(instr->temp());
1954 void LCodeGen::DoConstantE(LConstantE* instr) {
1955 __ lea(ToRegister(instr->result()), Operand::StaticVariable(instr->value()));
1959 void LCodeGen::DoConstantT(LConstantT* instr) {
1960 Register reg = ToRegister(instr->result());
1961 Handle<Object> handle = instr->value(isolate());
1967 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1968 Register result = ToRegister(instr->result());
1969 Register map = ToRegister(instr->value());
1974 void LCodeGen::DoElementsKind(LElementsKind* instr) {
1975 Register result = ToRegister(instr->result());
1976 Register input = ToRegister(instr->value());
1989 void LCodeGen::DoValueOf(LValueOf* instr) {
1990 Register input = ToRegister(instr->value());
1991 Register result = ToRegister(instr->result());
1992 Register map = ToRegister(instr->temp());
1997 if (!instr->hydrogen()->value()->IsHeapObject()) {
2011 void LCodeGen::DoDateField(LDateField* instr) {
2012 Register object = ToRegister(instr->date());
2013 Register result = ToRegister(instr->result());
2014 Register scratch = ToRegister(instr->temp());
2015 Smi* index = instr->index();
2021 DeoptimizeIf(zero, instr->environment());
2023 DeoptimizeIf(not_equal, instr->environment());
2066 void LCodeGen::DoSeqStringGetChar(LSeqStringGetChar* instr) {
2067 String::Encoding encoding = instr->hydrogen()->encoding();
2068 Register result = ToRegister(instr->result());
2069 Register string = ToRegister(instr->string());
2085 Operand operand = BuildSeqStringOperand(string, instr->index(), encoding);
2094 void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
2095 String::Encoding encoding = instr->hydrogen()->encoding();
2096 Register string = ToRegister(instr->string());
2099 Register value = ToRegister(instr->value());
2100 Register index = ToRegister(instr->index());
2104 instr->hydrogen()->encoding() == String::ONE_BYTE_ENCODING
2109 Operand operand = BuildSeqStringOperand(string, instr->index(), encoding);
2110 if (instr->value()->IsConstantOperand()) {
2111 int value = ToRepresentation(LConstantOperand::cast(instr->value()),
2122 Register value = ToRegister(instr->value());
2132 void LCodeGen::DoThrow(LThrow* instr) {
2133 __ push(ToOperand(instr->value()));
2134 ASSERT(ToRegister(instr->context()).is(esi));
2135 CallRuntime(Runtime::kThrow, 1, instr);
2144 void LCodeGen::DoAddI(LAddI* instr) {
2145 LOperand* left = instr->left();
2146 LOperand* right = instr->right();
2148 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) {
2151 instr->hydrogen()->representation());
2152 __ lea(ToRegister(instr->result()), MemOperand(ToRegister(left), offset));
2155 __ lea(ToRegister(instr->result()), address);
2160 ToImmediate(right, instr->hydrogen()->representation()));
2164 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
2165 DeoptimizeIf(overflow, instr->environment());
2171 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
2173 LOperand* left = instr->left();
2174 LOperand* right = instr->right();
2175 ASSERT(left->Equals(instr->result()));
2176 HMathMinMax::Operation operation = instr->hydrogen()->operation();
2177 if (instr->hydrogen()->representation().IsSmiOrInteger32()) {
2184 Immediate immediate = ToImmediate(LConstantOperand::cast(instr->right()),
2185 instr->hydrogen()->representation());
2198 ASSERT(instr->hydrogen()->representation().IsDouble());
2234 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
2237 XMMRegister left = ToDoubleRegister(instr->left());
2238 XMMRegister right = ToDoubleRegister(instr->right());
2239 XMMRegister result = ToDoubleRegister(instr->result());
2240 switch (instr->op()) {
2278 X87Register left = ToX87Register(instr->left());
2279 X87Register right = ToX87Register(instr->right());
2280 X87Register result = ToX87Register(instr->result());
2281 if (instr->op() != Token::MOD) {
2284 switch (instr->op()) {
2321 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
2322 ASSERT(ToRegister(instr->context()).is(esi));
2323 ASSERT(ToRegister(instr->left()).is(edx));
2324 ASSERT(ToRegister(instr->right()).is(eax));
2325 ASSERT(ToRegister(instr->result()).is(eax));
2327 BinaryOpICStub stub(instr->op(), NO_OVERWRITE);
2328 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
2334 void LCodeGen::EmitBranch(InstrType instr, Condition cc) {
2335 int left_block = instr->TrueDestination(chunk_);
2336 int right_block = instr->FalseDestination(chunk_);
2354 void LCodeGen::EmitFalseBranch(InstrType instr, Condition cc) {
2355 int false_block = instr->FalseDestination(chunk_);
2364 void LCodeGen::DoBranch(LBranch* instr) {
2365 Representation r = instr->hydrogen()->value()->representation();
2367 Register reg = ToRegister(instr->value());
2369 EmitBranch(instr, not_zero);
2373 XMMRegister reg = ToDoubleRegister(instr->value());
2377 EmitBranch(instr, not_equal);
2380 Register reg = ToRegister(instr->value());
2381 HType type = instr->hydrogen()->value()->type();
2385 EmitBranch(instr, equal);
2389 EmitBranch(instr, not_equal);
2392 EmitBranch(instr, no_condition);
2399 EmitBranch(instr, not_equal);
2403 EmitBranch(instr, not_equal);
2405 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
2411 __ j(equal, instr->FalseLabel(chunk_));
2416 __ j(equal, instr->TrueLabel(chunk_));
2419 __ j(equal, instr->FalseLabel(chunk_));
2424 __ j(equal, instr->FalseLabel(chunk_));
2430 __ j(equal, instr->FalseLabel(chunk_));
2431 __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
2435 DeoptimizeIf(zero, instr->environment());
2440 map = ToRegister(instr->temp());
2448 __ j(not_zero, instr->FalseLabel(chunk_));
2455 __ j(above_equal, instr->TrueLabel(chunk_));
2464 __ j(not_zero, instr->TrueLabel(chunk_));
2465 __ jmp(instr->FalseLabel(chunk_));
2472 __ j(equal, instr->TrueLabel(chunk_));
2491 __ j(zero, instr->FalseLabel(chunk_));
2492 __ jmp(instr->TrueLabel(chunk_));
2499 DeoptimizeIf(no_condition, instr->environment());
2513 void LCodeGen::DoClobberDoubles(LClobberDoubles* instr) {
2517 void LCodeGen::DoGoto(LGoto* instr) {
2518 EmitGoto(instr->block_id());
2554 void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) {
2555 LOperand* left = instr->left();
2556 LOperand* right = instr->right();
2557 Condition cc = TokenToCondition(instr->op(), instr->is_double());
2563 int next_block = EvalComparison(instr->op(), left_val, right_val) ?
2564 instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_);
2567 if (instr->is_double()) {
2577 __ j(parity_even, instr->FalseLabel(chunk_));
2581 ToImmediate(right, instr->hydrogen()->representation()));
2584 ToImmediate(left, instr->hydrogen()->representation()));
2591 EmitBranch(instr, cc);
2596 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
2597 Register left = ToRegister(instr->left());
2599 if (instr->right()->IsConstantOperand()) {
2600 Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right()));
2603 Operand right = ToOperand(instr->right());
2606 EmitBranch(instr, equal);
2610 void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
2611 if (instr->hydrogen()->representation().IsTagged()) {
2612 Register input_reg = ToRegister(instr->object());
2614 EmitBranch(instr, equal);
2621 XMMRegister input_reg = ToDoubleRegister(instr->object());
2623 EmitFalseBranch(instr, parity_odd);
2626 X87Register src = ToX87Register(instr->object());
2634 EmitFalseBranch(instr, no_condition);
2642 XMMRegister input_reg = ToDoubleRegister(instr->object());
2651 EmitBranch(instr, equal);
2655 void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
2656 Representation rep = instr->hydrogen()->value()->representation();
2658 Register scratch = ToRegister(instr->temp());
2662 XMMRegister value = ToDoubleRegister(instr->value());
2666 EmitFalseBranch(instr, not_equal);
2669 EmitBranch(instr, not_zero);
2671 Register value = ToRegister(instr->value());
2673 __ CheckMap(value, map, instr->FalseLabel(chunk()), DO_SMI_CHECK);
2676 EmitFalseBranch(instr, not_equal);
2679 EmitBranch(instr, equal);
2707 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
2708 Register reg = ToRegister(instr->value());
2709 Register temp = ToRegister(instr->temp());
2712 reg, temp, instr->FalseLabel(chunk_), instr->TrueLabel(chunk_));
2714 EmitBranch(instr, true_cond);
2732 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
2733 Register reg = ToRegister(instr->value());
2734 Register temp = ToRegister(instr->temp());
2737 instr->hydrogen()->value()->IsHeapObject()
2741 reg, temp, instr->FalseLabel(chunk_), check_needed);
2743 EmitBranch(instr, true_cond);
2747 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
2748 Operand input = ToOperand(instr->value());
2751 EmitBranch(instr, zero);
2755 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
2756 Register input = ToRegister(instr->value());
2757 Register temp = ToRegister(instr->temp());
2759 if (!instr->hydrogen()->value()->IsHeapObject()) {
2761 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2766 EmitBranch(instr, not_zero);
2790 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
2791 Token::Value op = instr->op();
2794 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2799 EmitBranch(instr, condition);
2803 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
2804 InstanceType from = instr->from();
2805 InstanceType to = instr->to();
2812 static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
2813 InstanceType from = instr->from();
2814 InstanceType to = instr->to();
2823 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
2824 Register input = ToRegister(instr->value());
2825 Register temp = ToRegister(instr->temp());
2827 if (!instr->hydrogen()->value()->IsHeapObject()) {
2828 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2831 __ CmpObjectType(input, TestType(instr->hydrogen()), temp);
2832 EmitBranch(instr, BranchCondition(instr->hydrogen()));
2836 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
2837 Register input = ToRegister(instr->value());
2838 Register result = ToRegister(instr->result());
2848 LHasCachedArrayIndexAndBranch* instr) {
2849 Register input = ToRegister(instr->value());
2853 EmitBranch(instr, equal);
2922 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2923 Register input = ToRegister(instr->value());
2924 Register temp = ToRegister(instr->temp());
2925 Register temp2 = ToRegister(instr->temp2());
2927 Handle<String> class_name = instr->hydrogen()->class_name();
2929 EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
2932 EmitBranch(instr, equal);
2936 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
2937 Register reg = ToRegister(instr->value());
2938 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map());
2939 EmitBranch(instr, equal);
2943 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
2945 ASSERT(ToRegister(instr->context()).is(esi));
2947 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
2952 __ mov(ToRegister(instr->result()), factory()->false_value());
2955 __ mov(ToRegister(instr->result()), factory()->true_value());
2960 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
2964 LInstanceOfKnownGlobal* instr,
2966 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
2970 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
2978 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr, x87_stack_);
2981 Register object = ToRegister(instr->value());
2982 Register temp = ToRegister(instr->temp());
2991 Register map = ToRegister(instr->temp());
3015 __ mov(ToRegister(instr->result()), factory()->false_value());
3024 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
3041 Register temp = ToRegister(instr->temp());
3043 __ LoadHeapObject(InstanceofStub::right(), instr->function());
3050 instr,
3054 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment();
3062 void LCodeGen::DoCmpT(LCmpT* instr) {
3063 Token::Value op = instr->op();
3066 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3072 __ mov(ToRegister(instr->result()), factory()->false_value());
3075 __ mov(ToRegister(instr->result()), factory()->true_value());
3080 void LCodeGen::EmitReturn(LReturn* instr, bool dynamic_frame_alignment) {
3083 if (instr->has_constant_parameter_count()) {
3084 int parameter_count = ToInteger32(instr->constant_parameter_count());
3093 Register reg = ToRegister(instr->parameter_count());
3105 // emit code to restore stack based on instr->parameter_count()
3117 void LCodeGen::DoReturn(LReturn* instr) {
3146 EmitReturn(instr, true);
3150 EmitReturn(instr, false);
3157 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
3158 Register result = ToRegister(instr->result());
3159 __ mov(result, Operand::ForCell(instr->hydrogen()->cell().handle()));
3160 if (instr->hydrogen()->RequiresHoleCheck()) {
3162 DeoptimizeIf(equal, instr->environment());
3167 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
3168 ASSERT(ToRegister(instr->context()).is(esi));
3169 ASSERT(ToRegister(instr->global_object()).is(edx));
3170 ASSERT(ToRegister(instr->result()).is(eax));
3172 __ mov(ecx, instr->name());
3173 RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET :
3176 CallCode(ic, mode, instr);
3180 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
3181 Register value = ToRegister(instr->value());
3182 Handle<PropertyCell> cell_handle = instr->hydrogen()->cell().handle();
3188 if (instr->hydrogen()->RequiresHoleCheck()) {
3190 DeoptimizeIf(equal, instr->environment());
3199 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) {
3200 ASSERT(ToRegister(instr->context()).is(esi));
3201 ASSERT(ToRegister(instr->global_object()).is(edx));
3202 ASSERT(ToRegister(instr->value()).is(eax));
3204 __ mov(ecx, instr->name());
3205 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
3208 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr);
3212 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
3213 Register context = ToRegister(instr->context());
3214 Register result = ToRegister(instr->result());
3215 __ mov(result, ContextOperand(context, instr->slot_index()));
3217 if (instr->hydrogen()->RequiresHoleCheck()) {
3219 if (instr->hydrogen()->DeoptimizesOnHole()) {
3220 DeoptimizeIf(equal, instr->environment());
3231 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
3232 Register context = ToRegister(instr->context());
3233 Register value = ToRegister(instr->value());
3237 Operand target = ContextOperand(context, instr->slot_index());
3238 if (instr->hydrogen()->RequiresHoleCheck()) {
3240 if (instr->hydrogen()->DeoptimizesOnHole()) {
3241 DeoptimizeIf(equal, instr->environment());
3248 if (instr->hydrogen()->NeedsWriteBarrier()) {
3250 instr->hydrogen()->value()->IsHeapObject()
3252 Register temp = ToRegister(instr->temp());
3253 int offset = Context::SlotOffset(instr->slot_index());
3267 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
3268 HObjectAccess access = instr->hydrogen()->access();
3272 Register result = ToRegister(instr->result());
3273 MemOperand operand = instr->object()->IsConstantOperand()
3275 LConstantOperand::cast(instr->object())))
3276 : MemOperand(ToRegister(instr->object()), offset);
3281 Register object = ToRegister(instr->object());
3283 instr->hydrogen()->representation().IsDouble()) {
3286 XMMRegister result = ToDoubleRegister(instr->result());
3289 X87Mov(ToX87Register(instr->result()), FieldOperand(object, offset));
3294 Register result = ToRegister(instr->result());
3321 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
3322 ASSERT(ToRegister(instr->context()).is(esi));
3323 ASSERT(ToRegister(instr->object()).is(edx));
3324 ASSERT(ToRegister(instr->result()).is(eax));
3326 __ mov(ecx, instr->name());
3328 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3332 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
3333 Register function = ToRegister(instr->function());
3334 Register temp = ToRegister(instr->temp());
3335 Register result = ToRegister(instr->result());
3339 DeoptimizeIf(not_equal, instr->environment());
3353 DeoptimizeIf(equal, instr->environment());
3374 void LCodeGen::DoLoadRoot(LLoadRoot* instr) {
3375 Register result = ToRegister(instr->result());
3376 __ LoadRoot(result, instr->index());
3381 LLoadExternalArrayPointer* instr) {
3382 Register result = ToRegister(instr->result());
3383 Register input = ToRegister(instr->object());
3389 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
3390 Register arguments = ToRegister(instr->arguments());
3391 Register result = ToRegister(instr->result());
3392 if (instr->length()->IsConstantOperand() &&
3393 instr->index()->IsConstantOperand()) {
3394 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3395 int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
3399 Register length = ToRegister(instr->length());
3400 Operand index = ToOperand(instr->index());
3409 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
3410 ElementsKind elements_kind = instr->elements_kind();
3411 LOperand* key = instr->key();
3413 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(),
3418 instr->elements(),
3420 instr->hydrogen()->key()->representation(),
3423 instr->additional_index()));
3427 XMMRegister result(ToDoubleRegister(instr->result()));
3431 X87Mov(ToX87Register(instr->result()), operand, kX87FloatOperand);
3436 __ movsd(ToDoubleRegister(instr->result()), operand);
3438 X87Mov(ToX87Register(instr->result()), operand);
3441 Register result(ToRegister(instr->result()));
3461 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
3463 DeoptimizeIf(negative, instr->environment());
3483 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
3484 if (instr->hydrogen()->RequiresHoleCheck()) {
3488 instr->elements(), instr->key(),
3489 instr->hydrogen()->key()->representation(),
3492 instr->additional_index());
3494 DeoptimizeIf(equal, instr->environment());
3498 instr->elements(),
3499 instr->key(),
3500 instr
3503 instr->additional_index());
3506 XMMRegister result = ToDoubleRegister(instr->result());
3509 X87Mov(ToX87Register(instr->result()), double_load_operand);
3514 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3515 Register result = ToRegister(instr->result());
3519 BuildFastArrayOperand(instr->elements(),
3520 instr->key(),
3521 instr->hydrogen()->key()->representation(),
3524 instr->additional_index()));
3527 if (instr->hydrogen()->RequiresHoleCheck()) {
3528 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
3530 DeoptimizeIf(not_equal, instr->environment());
3533 DeoptimizeIf(equal, instr->environment());
3539 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
3540 if (instr->is_external()) {
3541 DoLoadKeyedExternalArray(instr);
3542 } else if (instr->hydrogen()->representation().IsDouble()) {
3543 DoLoadKeyedFixedDoubleArray(instr);
3545 DoLoadKeyedFixedArray(instr);
3582 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
3583 ASSERT(ToRegister(instr->context()).is(esi));
3584 ASSERT(ToRegister(instr->object()).is(edx));
3585 ASSERT(ToRegister(instr->key()).is(ecx));
3588 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3592 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
3593 Register result = ToRegister(instr->result());
3595 if (instr->hydrogen()->from_inlined()) {
3621 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
3622 Operand elem = ToOperand(instr->elements());
3623 Register result = ToRegister(instr->result());
3643 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
3644 Register receiver = ToRegister(instr->receiver());
3645 Register function = ToRegister(instr->function());
3646 Register scratch = ToRegister(instr->temp());
3675 DeoptimizeIf(equal, instr->environment());
3677 DeoptimizeIf(below, instr->environment());
3692 void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
3693 Register receiver = ToRegister(instr->receiver());
3694 Register function = ToRegister(instr->function());
3695 Register length = ToRegister(instr->length());
3696 Register elements = ToRegister(instr->elements());
3699 ASSERT(ToRegister(instr->result()).is(eax));
3705 DeoptimizeIf(above, instr->environment());
3723 ASSERT(instr->HasPointerMap());
3724 LPointerMap* pointers = instr->pointer_map();
3733 void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
3738 void LCodeGen::DoPushArgument(LPushArgument* instr) {
3739 LOperand* argument = instr->value();
3744 void LCodeGen::DoDrop(LDrop* instr) {
3745 __ Drop(instr->count());
3749 void LCodeGen::DoThisFunction(LThisFunction* instr) {
3750 Register result = ToRegister(instr->result());
3755 void LCodeGen::DoContext(LContext* instr) {
3756 Register result = ToRegister(instr->result());
3766 void LCodeGen::DoOuterContext(LOuterContext* instr) {
3767 Register context = ToRegister(instr->context());
3768 Register result = ToRegister(instr->result());
3774 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
3775 ASSERT(ToRegister(instr->context()).is(esi));
3777 __ push(Immediate(instr->hydrogen()->pairs()));
3778 __ push(Immediate(Smi::FromInt(instr->hydrogen()->flags())));
3779 CallRuntime(Runtime::kDeclareGlobals, 3, instr);
3783 void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
3784 Register context = ToRegister(instr->context());
3785 Register result = ToRegister(instr->result());
3791 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
3792 Register global = ToRegister(instr->global());
3793 Register result = ToRegister(instr->result());
3801 LInstruction* instr,
3830 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
3833 LPointerMap* pointers = instr->pointer_map();
3844 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
3845 ASSERT(ToRegister(instr->result()).is(eax));
3846 CallKnownFunction(instr->hydrogen()->function(),
3847 instr->hydrogen()->formal_parameter_count(),
3848 instr->arity(),
3849 instr,
3855 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3856 Register input_reg = ToRegister(instr->value());
3859 DeoptimizeIf(not_equal, instr->environment());
3882 instr, instr->context());
3900 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
3901 Register input_reg = ToRegister(instr->value());
3906 DeoptimizeIf(negative, instr->environment());
3911 void LCodeGen::DoMathAbs(LMathAbs* instr) {
3916 LMathAbs* instr,
3918 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
3922 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
3927 ASSERT(instr->value()->Equals(instr->result()));
3928 Representation r = instr->hydrogen()->value()->representation();
3933 XMMRegister input_reg = ToDoubleRegister(instr->value());
3938 EmitIntegerMathAbs(instr);
3941 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr, x87_stack_);
3942 Register input_reg = ToRegister(instr->value());
3945 EmitIntegerMathAbs(instr);
3951 void LCodeGen::DoMathFloor(LMathFloor* instr) {
3954 Register output_reg = ToRegister(instr->result());
3955 XMMRegister input_reg = ToDoubleRegister(instr->value());
3959 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3967 DeoptimizeIf(not_zero, instr->environment());
3974 DeoptimizeIf(equal, instr->environment());
3980 DeoptimizeIf(parity_even, instr->environment());
3983 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3989 DeoptimizeIf(not_zero, instr->environment());
3999 DeoptimizeIf(equal, instr->environment());
4010 DeoptimizeIf(overflow, instr->environment());
4017 void LCodeGen::DoMathRound(LMathRound* instr) {
4019 Register output_reg = ToRegister(instr->result());
4020 XMMRegister input_reg = ToDoubleRegister(instr->value());
4022 XMMRegister input_temp = ToDoubleRegister(instr->temp());
4040 DeoptimizeIf(equal, instr->environment());
4056 DeoptimizeIf(equal, instr->environment());
4068 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
4073 DeoptimizeIf(not_zero, instr->environment());
4080 void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
4082 XMMRegister input_reg = ToDoubleRegister(instr->value());
4083 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
4088 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
4091 XMMRegister input_reg = ToDoubleRegister(instr->value());
4092 Register scratch = ToRegister(instr->temp());
4093 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
4123 void LCodeGen::DoPower(LPower* instr) {
4124 Representation exponent_type = instr->hydrogen()->right()->representation();
4127 ASSERT(!instr->right()->IsDoubleRegister() ||
4128 ToDoubleRegister(instr->right()).is(xmm1));
4129 ASSERT(!instr->right()->IsRegister() ||
4130 ToRegister(instr->right()).is(eax));
4131 ASSERT(ToDoubleRegister(instr->left()).is(xmm2));
4132 ASSERT(ToDoubleRegister(instr->result()).is(xmm3));
4141 DeoptimizeIf(not_equal, instr->environment());
4156 void LCodeGen::DoMathLog(LMathLog* instr) {
4158 ASSERT(instr->value()->Equals(instr->result()));
4159 XMMRegister input_reg = ToDoubleRegister(instr->value());
4188 void LCodeGen::DoMathExp(LMathExp* instr) {
4190 XMMRegister input = ToDoubleRegister(instr->value());
4191 XMMRegister result = ToDoubleRegister(instr->result());
4193 Register temp1 = ToRegister(instr->temp1());
4194 Register temp2 = ToRegister(instr->temp2());
4200 void LCodeGen::DoMathTan(LMathTan* instr) {
4201 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
4207 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4211 void LCodeGen::DoMathCos(LMathCos* instr) {
4212 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
4218 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4222 void LCodeGen::DoMathSin(LMathSin* instr) {
4223 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
4229 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4233 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
4234 ASSERT(ToRegister(instr->context()).is(esi));
4235 ASSERT(ToRegister(instr->function()).is(edi));
4236 ASSERT(instr->HasPointerMap());
4238 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
4240 LPointerMap* pointers = instr->pointer_map();
4243 ParameterCount count(instr->arity());
4247 instr->hydrogen()->formal_parameter_count(),
4248 instr->arity(),
4249 instr,
4256 void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
4257 ASSERT(ToRegister(instr->context()).is(esi));
4258 ASSERT(ToRegister(instr->key()).is(ecx));
4259 ASSERT(ToRegister(instr->result()).is(eax));
4261 int arity = instr->arity();
4264 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4268 void LCodeGen::DoCallNamed(LCallNamed* instr) {
4269 ASSERT(ToRegister(instr->context()).is(esi));
4270 ASSERT(ToRegister(instr->result()).is(eax));
4272 int arity = instr->arity();
4276 __ mov(ecx, instr->name());
4277 CallCode(ic, mode, instr);
4281 void LCodeGen::DoCallFunction(LCallFunction* instr) {
4282 ASSERT(ToRegister(instr->context()).is(esi));
4283 ASSERT(ToRegister(instr->function()).is(edi));
4284 ASSERT(ToRegister(instr->result()).is(eax));
4286 int arity = instr->arity();
4288 if (instr->hydrogen()->IsTailCall()) {
4292 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4297 void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
4298 ASSERT(ToRegister(instr->context()).is(esi));
4299 ASSERT(ToRegister(instr->result()).is(eax));
4301 int arity = instr->arity();
4305 __ mov(ecx, instr->name());
4306 CallCode(ic, mode, instr);
4310 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
4311 ASSERT(ToRegister(instr->result()).is(eax));
4312 CallKnownFunction(instr->hydrogen()->target(),
4313 instr->hydrogen()->formal_parameter_count(),
4314 instr->arity(),
4315 instr,
4321 void LCodeGen::DoCallNew(LCallNew* instr) {
4322 ASSERT(ToRegister(instr->context()).is(esi));
4323 ASSERT(ToRegister(instr->constructor()).is(edi));
4324 ASSERT(ToRegister(instr->result()).is(eax));
4330 __ Set(eax, Immediate(instr->arity()));
4331 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4335 void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
4336 ASSERT(ToRegister(instr->context()).is(esi));
4337 ASSERT(ToRegister(instr->constructor()).is(edi));
4338 ASSERT(ToRegister(instr->result()).is(eax));
4340 __ Set(eax, Immediate(instr->arity()));
4341 __ mov(ebx, instr->hydrogen()->property_cell());
4342 ElementsKind kind = instr->hydrogen()->elements_kind();
4349 if (instr->arity() == 0) {
4351 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4352 } else if (instr->arity() == 1) {
4365 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4371 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4375 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4380 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
4381 ASSERT(ToRegister(instr->context()).is(esi));
4382 CallRuntime(instr->function(), instr->arity(), instr, instr->save_doubles());
4386 void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) {
4387 Register function = ToRegister(instr->function());
4388 Register code_object = ToRegister(instr->code_object());
4394 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
4395 Register result = ToRegister(instr->result());
4396 Register base = ToRegister(instr->base_object());
4397 if (instr->offset()->IsConstantOperand()) {
4398 LConstantOperand* offset = LConstantOperand::cast(instr->offset());
4401 Register offset = ToRegister(instr->offset());
4407 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
4408 Representation representation = instr->representation();
4410 HObjectAccess access = instr->hydrogen()->access();
4414 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4415 MemOperand operand = instr->object()->IsConstantOperand()
4417 ToExternalReference(LConstantOperand::cast(instr->object())))
4418 : MemOperand(ToRegister(instr->object()), offset);
4419 if (instr->value()->IsConstantOperand()) {
4420 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4423 Register value = ToRegister(instr->value());
4429 Register object = ToRegister(instr->object());
4430 Handle<Map> transition = instr->transition();
4433 if (instr->value()->IsConstantOperand()) {
4434 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4436 DeoptimizeIf(no_condition, instr->environment());
4440 if (instr->value()->IsConstantOperand()) {
4441 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4443 DeoptimizeIf(no_condition, instr->environment());
4446 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
4447 Register value = ToRegister(instr->value());
4449 DeoptimizeIf(zero, instr->environment());
4455 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4458 XMMRegister value = ToDoubleRegister(instr->value());
4461 X87Register value = ToX87Register(instr->value());
4468 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) {
4471 Register temp = ToRegister(instr->temp());
4472 Register temp_map = ToRegister(instr->temp_map());
4488 instr->hydrogen()->value()->IsHeapObject()
4493 write_register = ToRegister(instr->temp());
4498 if (instr->value()->IsConstantOperand()) {
4499 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4505 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4509 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4513 Register value = ToRegister(instr->value());
4517 if (instr->hydrogen()->NeedsWriteBarrier()) {
4518 Register value = ToRegister(instr->value());
4519 Register temp = access.IsInobject() ? ToRegister(instr->temp()) : object;
4532 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
4533 ASSERT(ToRegister(instr->context()).is(esi));
4534 ASSERT(ToRegister(instr->object()).is(edx));
4535 ASSERT(ToRegister(instr->value()).is(eax));
4537 __ mov(ecx, instr->name());
4538 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
4541 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4557 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
4558 if (instr->hydrogen()->skip_check() && !FLAG_debug_code) return;
4560 if (instr->index()->IsConstantOperand()) {
4562 ToImmediate(LConstantOperand::cast(instr->index()),
4563 instr->hydrogen()->length()->representation());
4564 __ cmp(ToOperand(instr->length()), immediate);
4566 instr->hydrogen()->allow_equality() ? below : below_equal;
4567 ApplyCheckIf(condition, instr);
4569 __ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
4571 instr->hydrogen()->allow_equality() ? above : above_equal;
4572 ApplyCheckIf(condition, instr);
4577 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4578 ElementsKind elements_kind = instr->elements_kind();
4579 LOperand* key = instr->key();
4581 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(),
4586 instr->elements(),
4588 instr->hydrogen()->key()->representation(),
4591 instr->additional_index()));
4596 __ cvtsd2ss(xmm_scratch, ToDoubleRegister(instr->value()));
4605 __ movsd(operand, ToDoubleRegister(instr->value()));
4607 X87Mov(operand, ToX87Register(instr->value()));
4610 Register value = ToRegister(instr->value());
4642 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
4646 instr->elements(),
4647 instr->key(),
4648 instr->hydrogen()->key()->representation(),
4651 instr->additional_index());
4655 XMMRegister value = ToDoubleRegister(instr->value());
4657 if (instr->NeedsCanonicalization()) {
4670 if (instr->hydrogen()->IsConstantHoleStore()) {
4680 instr->elements(),
4681 instr->key(),
4682 instr->hydrogen()->key()->representation(),
4685 instr->additional_index());
4689 X87Register value = ToX87Register(instr->value());
4692 if (instr->NeedsCanonicalization()) {
4718 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4719 Register elements = ToRegister(instr->elements());
4720 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
4723 instr->elements(),
4724 instr->key(),
4725 instr->hydrogen()->key()->representation(),
4728 instr->additional_index());
4729 if (instr->value()->IsRegister()) {
4730 __ mov(operand, ToRegister(instr->value()));
4732 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4743 if (instr->hydrogen()->NeedsWriteBarrier()) {
4744 ASSERT(instr->value()->IsRegister());
4745 Register value = ToRegister(instr->value());
4746 ASSERT(!instr->key()->IsConstantOperand());
4748 instr->hydrogen()->value()->IsHeapObject()
4762 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
4764 if (instr->is_external()) {
4765 DoStoreKeyedExternalArray(instr);
4766 } else if (instr->hydrogen()->value()->representation().IsDouble()) {
4767 DoStoreKeyedFixedDoubleArray(instr);
4769 DoStoreKeyedFixedArray(instr);
4774 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
4775 ASSERT(ToRegister(instr->context()).is(esi));
4776 ASSERT(ToRegister(instr->object()).is(edx));
4777 ASSERT(ToRegister(instr->key()).is(ecx));
4778 ASSERT(ToRegister(instr->value()).is(eax));
4780 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
4783 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4787 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
4788 Register object = ToRegister(instr->object());
4789 Register temp = ToRegister(instr->temp());
4792 DeoptimizeIf(equal, instr->environment());
4797 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
4798 Register object_reg = ToRegister(instr->object());
4800 Handle<Map> from_map = instr->original_map();
4801 Handle<Map> to_map = instr->transitioned_map();
4802 ElementsKind from_kind = instr->from_kind();
4803 ElementsKind to_kind = instr->to_kind();
4813 Register new_map_reg = ToRegister(instr->new_map_temp());
4817 ASSERT_NE(instr->temp(), NULL);
4819 ToRegister(instr->temp()),
4822 ASSERT(ToRegister(instr->context()).is(esi));
4831 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4837 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
4841 LStringCharCodeAt* instr,
4843 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
4847 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4853 new(zone()) DeferredStringCharCodeAt(this, instr, x87_stack_);
4857 ToRegister(instr->string()),
4858 ToRegister(instr->index()),
4859 ToRegister(instr->result()),
4865 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
4866 Register string = ToRegister(instr->string());
4867 Register result = ToRegister(instr->result());
4879 if (instr->index()->IsConstantOperand()) {
4880 Immediate immediate = ToImmediate(LConstantOperand::cast(instr->index()),
4884 Register index = ToRegister(instr->index());
4889 instr, instr->context());
4896 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
4900 LStringCharFromCode* instr,
4902 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
4906 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4912 new(zone()) DeferredStringCharFromCode(this, instr, x87_stack_);
4914 ASSERT(instr->hydrogen()->value()->representation().IsInteger32());
4915 Register char_code = ToRegister(instr->char_code());
4916 Register result = ToRegister(instr->result());
4931 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
4932 Register char_code = ToRegister(instr->char_code());
4933 Register result = ToRegister(instr->result());
4943 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context());
4948 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4949 ASSERT(ToRegister(instr->context()).is(esi));
4951 ASSERT(ToRegister(instr->left()).is(edx));
4952 ASSERT(ToRegister(instr->right()).is(eax));
4953 NewStringAddStub stub(instr->hydrogen()->flags(),
4955 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4957 EmitPushTaggedOperand(instr->left());
4958 EmitPushTaggedOperand(instr->right());
4959 StringAddStub stub(instr->hydrogen()->flags());
4960 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4965 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4966 LOperand* input = instr->value();
4967 LOperand* output = instr->result();
4984 void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) {
4985 Register input = ToRegister(instr->value());
4987 if (!instr->hydrogen()->value()->HasRange() ||
4988 !instr->hydrogen()->value()->range()->IsInSmiRange()) {
4989 DeoptimizeIf(overflow, instr->environment());
4994 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4995 LOperand* input = instr->value();
4996 LOperand* output = instr->result();
4999 LOperand* temp = instr->temp();
5013 void LCodeGen::DoUint32ToSmi(LUint32ToSmi* instr) {
5014 Register input = ToRegister(instr->value());
5015 if (!instr->hydrogen()->value()->HasRange() ||
5016 !instr->hydrogen()->value()->range()->IsInSmiRange()) {
5018 DeoptimizeIf(not_zero, instr->environment());
5024 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
5028 LNumberTagI* instr,
5030 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
5034 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5039 LOperand* input = instr->value();
5040 ASSERT(input->IsRegister() && input->Equals(instr->result()));
5044 new(zone()) DeferredNumberTagI(this, instr, x87_stack_);
5051 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
5055 LNumberTagU* instr,
5057 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
5061 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5066 LOperand* input = instr->value();
5067 ASSERT(input->IsRegister() && input->Equals(instr->result()));
5071 new(zone()) DeferredNumberTagU(this, instr, x87_stack_);
5079 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
5110 ToDoubleRegister(LNumberTagU::cast(instr)->temp()));
5142 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
5158 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
5162 LNumberTagD* instr,
5164 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
5168 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5173 Register reg = ToRegister(instr->result());
5178 X87Register src = ToX87Register(instr->value());
5183 new(zone()) DeferredNumberTagD(this, instr, x87_stack_);
5185 Register tmp = ToRegister(instr->temp());
5193 XMMRegister input_reg = ToDoubleRegister(instr->value());
5201 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
5205 Register reg = ToRegister(instr->result());
5217 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
5222 void LCodeGen::DoSmiTag(LSmiTag* instr) {
5223 LOperand* input = instr->value();
5224 ASSERT(input->IsRegister() && input->Equals(instr->result()));
5225 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
5230 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
5231 LOperand* input = instr->value();
5233 ASSERT(input->IsRegister() && input->Equals(instr->result()));
5234 if (instr->needs_check()) {
5236 DeoptimizeIf(not_zero, instr->environment());
5376 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) {
5377 Register input_reg = ToRegister(instr->value());
5379 if (instr->truncating()) {
5406 DeoptimizeIf(not_equal, instr->environment());
5411 XMMRegister scratch = (instr->temp() != NULL)
5412 ? ToDoubleRegister(instr->temp())
5415 instr->hydrogen()->GetMinusZeroMode(), &bailout);
5418 DeoptimizeIf(no_condition, instr->environment());
5423 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
5427 LTaggedToI* instr,
5429 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
5433 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5438 LOperand* input = instr->value();
5441 ASSERT(input_reg.is(ToRegister(instr->result())));
5443 if (instr->hydrogen()->value()->representation().IsSmi()) {
5447 new(zone()) DeferredTaggedToI(this, instr, x87_stack_);
5456 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
5457 LOperand* input = instr->value();
5459 LOperand* temp = instr->temp();
5461 LOperand* result = instr->result();
5466 instr->hydrogen()->deoptimize_on_minus_zero();
5469 HValue* value = instr->hydrogen()->value();
5479 instr->hydrogen()->can_convert_undefined_to_nan(),
5481 instr->environment(),
5486 ToX87Register(instr->result()),
5487 instr->hydrogen()->can_convert_undefined_to_nan(),
5489 instr->environment(),
5495 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
5496 LOperand* input = instr->value();
5498 LOperand* result = instr->result();
5502 if (instr->truncating()) {
5519 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);
5523 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(),
5528 DeoptimizeIf(no_condition, instr->environment());
5534 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
5535 LOperand* input = instr->value();
5537 LOperand* result = instr->result();
5547 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);
5551 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(),
5556 DeoptimizeIf(no_condition, instr->environment());
5560 DeoptimizeIf(overflow, instr->environment());
5564 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
5565 LOperand* input = instr->value();
5567 DeoptimizeIf(not_zero, instr->environment());
5571 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
5572 if (!instr->hydrogen()->value()->IsHeapObject()) {
5573 LOperand* input = instr->value();
5575 DeoptimizeIf(zero, instr->environment());
5580 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
5581 Register input = ToRegister(instr->value());
5582 Register temp = ToRegister(instr->temp());
5586 if (instr->hydrogen()->is_interval_check()) {
5589 instr->hydrogen()->GetCheckInterval(&first, &last);
5596 DeoptimizeIf(not_equal, instr->environment());
5598 DeoptimizeIf(below, instr->environment());
5603 DeoptimizeIf(above, instr->environment());
5609 instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
5614 DeoptimizeIf(tag == 0 ? not_zero : zero, instr->environment());
5619 DeoptimizeIf(not_equal, instr->environment());
5625 void LCodeGen::DoCheckValue(LCheckValue* instr) {
5626 Handle<HeapObject> object = instr->hydrogen()->object().handle();
5627 if (instr->hydrogen()->object_in_new_space()) {
5628 Register reg = ToRegister(instr->value());
5632 Operand operand = ToOperand(instr->value());
5635 DeoptimizeIf(not_equal, instr->environment());
5639 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
5646 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt);
5650 DeoptimizeIf(zero, instr->environment());
5654 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
5658 LCheckMaps* instr,
5661 : LDeferredCode(codegen, x87_stack), instr_(instr), object_(object) {
5668 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5675 if (instr->hydrogen()->CanOmitMapChecks()) return;
5677 LOperand* input = instr->value();
5682 if (instr->hydrogen()->has_migration_target()) {
5683 deferred = new(zone()) DeferredCheckMaps(this, instr, reg, x87_stack_);
5687 UniqueSet<Map> map_set = instr->hydrogen()->map_set();
5697 if (instr->hydrogen()->has_migration_target()) {
5700 DeoptimizeIf(not_equal, instr->environment());
5707 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
5709 XMMRegister value_reg = ToDoubleRegister(instr->unclamped());
5711 Register result_reg = ToRegister(instr->result());
5716 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
5717 ASSERT(instr->unclamped()->Equals(instr->result()));
5718 Register value_reg = ToRegister(instr->result());
5723 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
5726 ASSERT(instr->unclamped()->Equals(instr->result()));
5727 Register input_reg = ToRegister(instr->unclamped());
5728 XMMRegister temp_xmm_reg = ToDoubleRegister(instr->temp_xmm());
5742 DeoptimizeIf(not_equal, instr->environment());
5760 void LCodeGen::DoClampTToUint8NoSSE2(LClampTToUint8NoSSE2* instr) {
5761 Register input_reg = ToRegister(instr->unclamped());
5762 Register result_reg = ToRegister(instr->result());
5763 Register scratch = ToRegister(instr->scratch());
5764 Register scratch2 = ToRegister(instr->scratch2());
5765 Register scratch3 = ToRegister(instr->scratch3());
5779 DeoptimizeIf(not_equal, instr->environment());
5882 void LCodeGen::DoAllocate(LAllocate* instr) {
5886 LAllocate* instr,
5888 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
5892 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5898 new(zone()) DeferredAllocate(this, instr, x87_stack_);
5900 Register result = ToRegister(instr->result());
5901 Register temp = ToRegister(instr->temp());
5905 if (instr->hydrogen()->MustAllocateDoubleAligned()) {
5908 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5909 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation());
5910 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5912 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5913 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5917 if (instr->size()->IsConstantOperand()) {
5918 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5925 Register size = ToRegister(instr->size());
5931 if (instr->hydrogen()->MustPrefillWithFiller()) {
5932 if (instr->size()->IsConstantOperand()) {
5933 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5936 temp = ToRegister(instr->size());
5950 void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
5951 Register result = ToRegister(instr->result());
5959 if (instr->size()->IsRegister()) {
5960 Register size = ToRegister(instr->size());
5962 __ SmiTag(ToRegister(instr->size()));
5965 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5970 instr->hydrogen()->MustAllocateDoubleAligned());
5971 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5972 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation());
5973 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5975 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5976 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5984 Runtime::kAllocateInTargetSpace, 2, instr, instr->context());
5989 void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
5990 ASSERT(ToRegister(instr->value()).is(eax));
5992 CallRuntime(Runtime::kToFastProperties, 1, instr);
5996 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
5997 ASSERT(ToRegister(instr->context()).is(esi));
6005 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
6006 __ LoadHeapObject(ecx, instr->hydrogen()->literals());
6014 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index())));
6015 __ push(Immediate(instr->hydrogen()->pattern()));
6016 __ push(Immediate(instr->hydrogen()->flags()));
6017 CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr);
6029 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr);
6048 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
6049 ASSERT(ToRegister(instr->context()).is(esi));
6052 bool pretenure = instr->hydrogen()->pretenure();
6053 if (!pretenure && instr->hydrogen()->has_no_literals()) {
6054 FastNewClosureStub stub(instr->hydrogen()->language_mode(),
6055 instr->hydrogen()->is_generator());
6056 __ mov(ebx, Immediate(instr->hydrogen()->shared_info()));
6057 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
6060 __ push(Immediate(instr->hydrogen()->shared_info()));
6063 CallRuntime(Runtime::kNewClosure, 3, instr);
6068 void LCodeGen::DoTypeof(LTypeof* instr) {
6069 ASSERT(ToRegister(instr->context()).is(esi));
6070 LOperand* input = instr->value();
6072 CallRuntime(Runtime::kTypeof, 1, instr);
6076 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
6077 Register input = ToRegister(instr->value());
6078 Condition final_branch_condition = EmitTypeofIs(instr, input);
6080 EmitBranch(instr, final_branch_condition);
6085 Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) {
6086 Label* true_label = instr->TrueLabel(chunk_);
6087 Label* false_label = instr->FalseLabel(chunk_);
6088 Handle<String> type_name = instr->type_literal();
6089 int left_block = instr->TrueDestination(chunk_);
6090 int right_block = instr->FalseDestination(chunk_);
6167 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
6168 Register temp = ToRegister(instr->temp());
6171 EmitBranch(instr, equal);
6207 void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
6209 ASSERT(instr->HasEnvironment());
6210 LEnvironment* env = instr->environment();
6216 void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
6217 Deoptimizer::BailoutType type = instr->hydrogen()->type();
6225 Comment(";;; deoptimize: %s", instr->hydrogen()->reason());
6226 DeoptimizeIf(no_condition, instr->environment(), type);
6230 void LCodeGen::DoDummy(LDummy* instr) {
6235 void LCodeGen::DoDummyUse(LDummyUse* instr) {
6240 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
6245 instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
6246 ASSERT(instr->HasEnvironment());
6247 LEnvironment* env = instr->environment();
6252 void LCodeGen::DoStackCheck(LStackCheck* instr) {
6256 LStackCheck* instr,
6258 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
6262 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
6267 ASSERT(instr->HasEnvironment());
6268 LEnvironment* env = instr->environment();
6271 if (instr->hydrogen()->is_function_entry()) {
6279 ASSERT(instr->context()->IsRegister());
6280 ASSERT(ToRegister(instr->context()).is(esi));
6283 instr);
6289 ASSERT(instr->hydrogen()->is_backwards_branch());
6292 new(zone()) DeferredStackCheck(this, instr, x87_stack_);
6298 __ bind(instr->done_label());
6299 deferred_stack_check->SetExit(instr->done_label());
6308 void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
6312 LEnvironment* environment = instr->environment();
6323 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
6324 ASSERT(ToRegister(instr->context()).is(esi));
6326 DeoptimizeIf(equal, instr->environment());
6329 DeoptimizeIf(equal, instr->environment());
6332 DeoptimizeIf(zero, instr->environment());
6336 DeoptimizeIf(below_equal, instr->environment());
6347 CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr);
6351 DeoptimizeIf(not_equal, instr->environment());
6356 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) {
6357 Register map = ToRegister(instr->map());
6358 Register result = ToRegister(instr->result());
6371 FieldOperand(result, FixedArray::SizeFor(instr->idx())));
6374 DeoptimizeIf(equal, instr->environment());
6378 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
6379 Register object = ToRegister(instr->value());
6380 __ cmp(ToRegister(instr->map()),
6382 DeoptimizeIf(not_equal, instr->environment());
6386 void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
6387 Register object = ToRegister(instr->object());
6388 Register index = ToRegister(instr->index());