Home | History | Annotate | Download | only in x64

Lines Matching refs:instr

331               code->instr()->hydrogen_value()->id(),
332 code->instr()->Mnemonic());
596 LInstruction* instr,
600 ASSERT(instr != NULL);
602 RecordSafepointWithLazyDeopt(instr, safepoint_mode, argc);
615 LInstruction* instr) {
616 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT, 0);
622 LInstruction* instr,
624 ASSERT(instr != NULL);
625 ASSERT(instr->HasPointerMap());
629 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0);
653 LInstruction* instr,
659 instr->pointer_map(), argc, Safepoint::kNoLazyDeopt);
843 LInstruction* instr, SafepointMode safepoint_mode, int argc) {
845 RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt);
849 instr->pointer_map(), argc, Safepoint::kLazyDeopt);
937 void LCodeGen::DoInstructionGap(LInstructionGap* instr) {
938 DoGap(instr);
942 void LCodeGen::DoParameter(LParameter* instr) {
947 void LCodeGen::DoCallStub(LCallStub* instr) {
948 ASSERT(ToRegister(instr->context()).is(rsi));
949 ASSERT(ToRegister(instr->result()).is(rax));
950 switch (instr->hydrogen()->major_key()) {
953 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
958 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
963 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
968 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
972 TranscendentalCacheStub stub(instr->transcendental_type(),
974 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
983 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
988 void LCodeGen::DoModI(LModI* instr) {
989 HMod* hmod = instr->hydrogen();
995 Register left_reg = ToRegister(instr->left());
996 ASSERT(left_reg.is(ToRegister(instr->result())));
1009 DeoptimizeIf(zero, instr->environment());
1018 Register left_reg = ToRegister(instr->left());
1020 Register right_reg = ToRegister(instr->right());
1023 Register result_reg = ToRegister(instr->result());
1031 DeoptimizeIf(zero, instr->environment());
1042 DeoptimizeIf(equal, instr->environment());
1064 DeoptimizeIf(zero, instr->environment());
1074 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
1075 ASSERT(instr->right()->IsConstantOperand());
1077 const Register dividend = ToRegister(instr->left());
1078 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right()));
1079 const Register result = ToRegister(instr->result());
1083 DeoptimizeIf(no_condition, instr->environment());
1097 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1098 DeoptimizeIf(zero, instr->environment());
1100 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1101 DeoptimizeIf(overflow, instr->environment());
1112 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1113 DeoptimizeIf(zero, instr->environment());
1123 Register reg1 = ToRegister(instr->temp());
1124 Register reg2 = ToRegister(instr->result());
1143 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1145 DeoptimizeIf(zero, instr->environment());
1157 void LCodeGen::DoDivI(LDivI* instr) {
1158 if (!instr->is_flooring() && instr->hydrogen()->HasPowerOf2Divisor()) {
1159 Register dividend = ToRegister(instr->left());
1161 HConstant::cast(instr->hydrogen()->right())->Integer32Value();
1170 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1172 DeoptimizeIf(zero, instr->environment());
1175 if (divisor == -1 && instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1177 DeoptimizeIf(zero, instr->environment());
1184 if (instr->hydrogen()->CheckFlag(
1202 DeoptimizeIf(not_zero, instr->environment());
1212 LOperand* right = instr->right();
1213 ASSERT(ToRegister(instr->result()).is(rax));
1214 ASSERT(ToRegister(instr->left()).is(rax));
1215 ASSERT(!ToRegister(instr->right()).is(rax));
1216 ASSERT(!ToRegister(instr->right()).is(rdx));
1222 if (instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) {
1224 DeoptimizeIf(zero, instr->environment());
1228 if (instr->hydrogen_value()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1233 DeoptimizeIf(sign, instr->environment());
1238 if (instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)) {
1243 DeoptimizeIf(zero, instr->environment());
1251 if (instr->is_flooring()) {
1259 } else if (!instr->hydrogen()->CheckFlag(
1263 DeoptimizeIf(not_zero, instr->environment());
1268 void LCodeGen::DoMulI(LMulI* instr) {
1269 Register left = ToRegister(instr->left());
1270 LOperand* right = instr->right();
1272 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1273 if (instr->hydrogen_value()->representation().IsSmi()) {
1281 instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1324 if (instr->hydrogen_value()->representation().IsSmi()) {
1331 if (instr->hydrogen_value()->representation().IsSmi()) {
1340 DeoptimizeIf(overflow, instr->environment());
1343 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1346 if (instr->hydrogen_value()->representation().IsSmi()) {
1354 ASSERT(!instr->hydrogen_value()->representation().IsSmi());
1356 DeoptimizeIf(no_condition, instr->environment());
1359 DeoptimizeIf(less, instr->environment());
1362 if (instr->hydrogen_value()->representation().IsSmi()) {
1367 DeoptimizeIf(sign, instr->environment());
1370 if (instr->hydrogen_value()->representation().IsSmi()) {
1375 DeoptimizeIf(sign, instr->environment());
1382 void LCodeGen::DoBitI(LBitI* instr) {
1383 LOperand* left = instr->left();
1384 LOperand* right = instr->right();
1385 ASSERT(left->Equals(instr->result()));
1390 switch (instr->op()) {
1409 switch (instr->op()) {
1425 switch (instr->op()) {
1443 void LCodeGen::DoShiftI(LShiftI* instr) {
1444 LOperand* left = instr->left();
1445 LOperand* right = instr->right();
1446 ASSERT(left->Equals(instr->result()));
1451 switch (instr->op()) {
1460 if (instr->can_deopt()) {
1462 DeoptimizeIf(negative, instr->environment());
1475 switch (instr->op()) {
1487 if (shift_count == 0 && instr->can_deopt()) {
1489 DeoptimizeIf(negative, instr->environment());
1496 if (instr->hydrogen_value()->representation().IsSmi()) {
1511 void LCodeGen::DoSubI(LSubI* instr) {
1512 LOperand* left = instr->left();
1513 LOperand* right = instr->right();
1514 ASSERT(left->Equals(instr->result()));
1520 if (instr->hydrogen_value()->representation().IsSmi()) {
1526 if (instr->hydrogen_value()->representation().IsSmi()) {
1533 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1534 DeoptimizeIf(overflow, instr->environment());
1539 instr) {
1540 __ Set(ToRegister(instr->result()), instr->value());
1544 void LCodeGen::DoConstantS(LConstantS* instr) {
1545 __ Move(ToRegister(instr->result()), instr->value());
1549 void LCodeGen::DoConstantD(LConstantD* instr) {
1550 ASSERT(instr->result()->IsDoubleRegister());
1551 XMMRegister res = ToDoubleRegister(instr->result());
1552 double v = instr->value();
1559 Register tmp = ToRegister(instr->temp());
1566 void LCodeGen::DoConstantE(LConstantE* instr) {
1567 __ LoadAddress(ToRegister(instr->result()), instr->value());
1571 void LCodeGen::DoConstantT(LConstantT* instr) {
1572 Handle<Object> value = instr->value(isolate());
1573 __ Move(ToRegister(instr->result()), value);
1577 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1578 Register result = ToRegister(instr->result());
1579 Register map = ToRegister(instr->value());
1584 void LCodeGen::DoElementsKind(LElementsKind* instr) {
1585 Register result = ToRegister(instr->result());
1586 Register input = ToRegister(instr->value());
1598 void LCodeGen::DoValueOf(LValueOf* instr) {
1599 Register input = ToRegister(instr->value());
1600 Register result = ToRegister(instr->result());
1604 if (!instr->hydrogen()->value()->IsHeapObject()) {
1618 void LCodeGen::DoDateField(LDateField* instr) {
1619 Register object = ToRegister(instr->date());
1620 Register result = ToRegister(instr->result());
1621 Smi* index = instr->index();
1627 DeoptimizeIf(cc, instr->environment());
1629 DeoptimizeIf(not_equal, instr->environment());
1673 void LCodeGen::DoSeqStringGetChar(LSeqStringGetChar* instr) {
1674 String::Encoding encoding = instr->hydrogen()->encoding();
1675 Register result = ToRegister(instr->result());
1676 Register string = ToRegister(instr->string());
1692 Operand operand = BuildSeqStringOperand(string, instr->index(), encoding);
1701 void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
1702 String::Encoding encoding = instr->hydrogen()->encoding();
1703 Register string = ToRegister(instr->string());
1706 Register value = ToRegister(instr->value());
1707 Register index = ToRegister(instr->index());
1711 instr->hydrogen()->encoding() == String::ONE_BYTE_ENCODING
1716 Operand operand = BuildSeqStringOperand(string, instr->index(), encoding);
1717 if (instr->value()->IsConstantOperand()) {
1718 int value = ToInteger32(LConstantOperand::cast(instr->value()));
1728 Register value = ToRegister(instr->value());
1738 void LCodeGen::DoThrow(LThrow* instr) {
1739 __ push(ToRegister(instr->value()));
1740 ASSERT(ToRegister(instr->context()).is(rsi));
1741 CallRuntime(Runtime::kThrow, 1, instr);
1750 void LCodeGen::DoAddI(LAddI* instr) {
1751 LOperand* left = instr->left();
1752 LOperand* right = instr->right();
1754 Representation target_rep = instr->hydrogen()->representation();
1757 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) {
1761 __ lea(ToRegister(instr->result()),
1764 __ leal(ToRegister(instr->result()),
1770 __ lea(ToRegister(instr->result()), address);
1772 __ leal(ToRegister(instr->result()), address);
1797 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1798 DeoptimizeIf(overflow, instr->environment());
1804 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
1805 LOperand* left = instr->left();
1806 LOperand* right = instr->right();
1807 ASSERT(left->Equals(instr->result()));
1808 HMathMinMax::Operation operation = instr->hydrogen()->operation();
1809 if (instr->hydrogen()->representation().IsSmiOrInteger32()) {
1818 ASSERT(!instr->hydrogen_value()->representation().IsSmi());
1824 if (instr->hydrogen_value()->representation().IsSmi()) {
1833 if (instr->hydrogen_value()->representation().IsSmi()) {
1843 ASSERT(instr->hydrogen()->representation().IsDouble());
1879 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1880 XMMRegister left = ToDoubleRegister(instr->left());
1881 XMMRegister right = ToDoubleRegister(instr->right());
1882 XMMRegister result = ToDoubleRegister(instr->result());
1884 ASSERT(instr->op() == Token::MOD || left.is(result));
1885 switch (instr->op()) {
1918 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
1919 ASSERT(ToRegister(instr->context()).is(rsi));
1920 ASSERT(ToRegister(instr->left()).is(rdx));
1921 ASSERT(ToRegister(instr->right()).is(rax));
1922 ASSERT(ToRegister(instr->result()).is(rax));
1924 BinaryOpICStub stub(instr->op(), NO_OVERWRITE);
1925 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1931 void LCodeGen::EmitBranch(InstrType instr, Condition cc) {
1932 int left_block = instr->TrueDestination(chunk_);
1933 int right_block = instr->FalseDestination(chunk_);
1953 void LCodeGen::EmitFalseBranch(InstrType instr, Condition cc) {
1954 int false_block = instr->FalseDestination(chunk_);
1959 void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
1964 void LCodeGen::DoBranch(LBranch* instr) {
1965 Representation r = instr->hydrogen()->value()->representation();
1968 Register reg = ToRegister(instr->value());
1970 EmitBranch(instr, not_zero);
1973 Register reg = ToRegister(instr->value());
1975 EmitBranch(instr, not_zero);
1978 XMMRegister reg = ToDoubleRegister(instr->value());
1982 EmitBranch(instr, not_equal);
1985 Register reg = ToRegister(instr->value());
1986 HType type = instr->hydrogen()->value()->type();
1990 EmitBranch(instr, equal);
1994 EmitBranch(instr, not_equal);
1997 EmitBranch(instr, no_condition);
2003 EmitBranch(instr, not_equal);
2007 EmitBranch(instr, not_equal);
2009 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
2016 __ j(equal, instr->FalseLabel(chunk_));
2021 __ j(equal, instr->TrueLabel(chunk_));
2024 instr->FalseLabel(chunk_));
2029 __ j(equal, instr->FalseLabel(chunk_));
2035 __ j(equal, instr->FalseLabel(chunk_));
2036 __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
2040 DeoptimizeIf(zero, instr->environment());
2051 __ j(not_zero, instr->FalseLabel(chunk_));
2058 __ j(above_equal, instr->TrueLabel(chunk_));
2067 __ j(not_zero, instr->TrueLabel(chunk_));
2068 __ jmp(instr->FalseLabel(chunk_));
2075 __ j(equal, instr->TrueLabel(chunk_));
2086 __ j(zero, instr->FalseLabel(chunk_));
2087 __ jmp(instr->TrueLabel(chunk_));
2094 DeoptimizeIf(no_condition, instr->environment());
2108 void LCodeGen::DoGoto(LGoto* instr) {
2109 EmitGoto(instr->block_id());
2145 void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) {
2146 LOperand* left = instr->left();
2147 LOperand* right = instr->right();
2148 Condition cc = TokenToCondition(instr->op(), instr->is_double());
2154 int next_block = EvalComparison(instr->op(), left_val, right_val) ?
2155 instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_);
2158 if (instr->is_double()) {
2162 __ j(parity_even, instr->FalseLabel(chunk_));
2167 if (instr->hydrogen_value()->representation().IsSmi()) {
2174 if (instr->hydrogen_value()->representation().IsSmi()) {
2187 } else if (instr->hydrogen_value()->representation().IsSmi()) {
2201 EmitBranch(instr, cc);
2206 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
2207 Register left = ToRegister(instr->left());
2209 if (instr->right()->IsConstantOperand()) {
2210 Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right()));
2213 Register right = ToRegister(instr->right());
2216 EmitBranch(instr, equal);
2220 void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
2221 if (instr->hydrogen()->representation().IsTagged()) {
2222 Register input_reg = ToRegister(instr->object());
2224 EmitBranch(instr, equal);
2228 XMMRegister input_reg = ToDoubleRegister(instr->object());
2230 EmitFalseBranch(instr, parity_odd);
2238 EmitBranch(instr, equal);
2242 void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
2243 Representation rep = instr->hydrogen()->value()->representation();
2247 XMMRegister value = ToDoubleRegister(instr->value());
2251 EmitFalseBranch(instr, not_equal);
2254 EmitBranch(instr, not_zero);
2256 Register value = ToRegister(instr->value());
2258 __ CheckMap(value, map, instr->FalseLabel(chunk()), DO_SMI_CHECK);
2261 EmitFalseBranch(instr, not_equal);
2264 EmitBranch(instr, equal);
2294 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
2295 Register reg = ToRegister(instr->value());
2298 reg, instr->FalseLabel(chunk_), instr->TrueLabel(chunk_));
2300 EmitBranch(instr, true_cond);
2318 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
2319 Register reg = ToRegister(instr->value());
2320 Register temp = ToRegister(instr->temp());
2323 instr->hydrogen()->value()->IsHeapObject()
2327 reg, temp, instr->FalseLabel(chunk_), check_needed);
2329 EmitBranch(instr, true_cond);
2333 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
2335 if (instr->value()->IsRegister()) {
2336 Register input = ToRegister(instr->value());
2339 Operand input = ToOperand(instr->value());
2342 EmitBranch(instr, is_smi);
2346 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
2347 Register input = ToRegister(instr->value());
2348 Register temp = ToRegister(instr->temp());
2350 if (!instr->hydrogen()->value()->IsHeapObject()) {
2351 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2356 EmitBranch(instr, not_zero);
2360 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
2361 ASSERT(ToRegister(instr->context()).is(rsi));
2362 Token::Value op = instr->op();
2365 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2370 EmitBranch(instr, condition);
2374 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
2375 InstanceType from = instr->from();
2376 InstanceType to = instr->to();
2383 static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
2384 InstanceType from = instr->from();
2385 InstanceType to = instr->to();
2394 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
2395 Register input = ToRegister(instr->value());
2397 if (!instr->hydrogen()->value()->IsHeapObject()) {
2398 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2401 __ CmpObjectType(input, TestType(instr->hydrogen()), kScratchRegister);
2402 EmitBranch(instr, BranchCondition(instr->hydrogen()));
2406 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
2407 Register input = ToRegister(instr->value());
2408 Register result = ToRegister(instr->result());
2419 LHasCachedArrayIndexAndBranch* instr) {
2420 Register input = ToRegister(instr->value());
2424 EmitBranch(instr, equal);
2496 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2497 Register input = ToRegister(instr->value());
2498 Register temp = ToRegister(instr->temp());
2499 Register temp2 = ToRegister(instr->temp2());
2500 Handle<String> class_name = instr->hydrogen()->class_name();
2502 EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
2505 EmitBranch(instr, equal);
2509 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
2510 Register reg = ToRegister(instr
2512 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map());
2513 EmitBranch(instr, equal);
2517 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
2518 ASSERT(ToRegister(instr->context()).is(rsi));
2520 __ push(ToRegister(instr->left()));
2521 __ push(ToRegister(instr->right()));
2522 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
2526 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
2529 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex);
2534 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
2538 LInstanceOfKnownGlobal* instr)
2539 : LDeferredCode(codegen), instr_(instr) { }
2543 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
2550 ASSERT(ToRegister(instr->context()).is(rsi));
2552 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
2555 Register object = ToRegister(instr->value());
2565 Register map = ToRegister(instr->temp());
2573 __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex);
2592 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
2599 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
2607 __ push(ToRegister(instr->value()));
2608 __ Push(instr->function());
2622 instr,
2626 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment();
2644 void LCodeGen::DoCmpT(LCmpT* instr) {
2645 ASSERT(ToRegister(instr->context()).is(rsi));
2646 Token::Value op = instr->op();
2649 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2655 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
2658 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex);
2663 void LCodeGen::DoReturn(LReturn* instr) {
2682 if (instr->has_constant_parameter_count()) {
2683 __ Ret((ToInteger32(instr->constant_parameter_count()) + 1) * kPointerSize,
2686 Register reg = ToRegister(instr->parameter_count());
2701 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
2702 Register result = ToRegister(instr->result());
2703 __ LoadGlobalCell(result, instr->hydrogen()->cell().handle());
2704 if (instr->hydrogen()->RequiresHoleCheck()) {
2706 DeoptimizeIf(equal, instr->environment());
2711 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
2712 ASSERT(ToRegister(instr->context()).is(rsi));
2713 ASSERT(ToRegister(instr->global_object()).is(rax));
2714 ASSERT(ToRegister(instr->result()).is(rax));
2716 __ Move(rcx, instr->name());
2717 RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET :
2720 CallCode(ic, mode, instr);
2724 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
2725 Register value = ToRegister(instr->value());
2726 Handle<Cell> cell_handle = instr->hydrogen()->cell().handle();
2732 if (instr->hydrogen()->RequiresHoleCheck()) {
2734 Register cell = ToRegister(instr->temp());
2738 DeoptimizeIf(equal, instr->environment());
2750 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) {
2751 ASSERT(ToRegister(instr->context()).is(rsi));
2752 ASSERT(ToRegister(instr->global_object()).is(rdx));
2753 ASSERT(ToRegister(instr->value()).is(rax));
2755 __ Move(rcx, instr->name());
2756 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
2759 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr);
2763 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
2764 Register context = ToRegister(instr->context());
2765 Register result = ToRegister(instr->result());
2766 __ movq(result, ContextOperand(context, instr->slot_index()));
2767 if (instr->hydrogen()->RequiresHoleCheck()) {
2769 if (instr->hydrogen()->DeoptimizesOnHole()) {
2770 DeoptimizeIf(equal, instr->environment());
2781 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
2782 Register context = ToRegister(instr->context());
2783 Register value = ToRegister(instr->value());
2785 Operand target = ContextOperand(context, instr->slot_index());
2788 if (instr->hydrogen()->RequiresHoleCheck()) {
2790 if (instr->hydrogen()->DeoptimizesOnHole()) {
2791 DeoptimizeIf(equal, instr->environment());
2798 if (instr->hydrogen()->NeedsWriteBarrier()) {
2800 instr->hydrogen()->value()->IsHeapObject()
2802 int offset = Context::SlotOffset(instr->slot_index());
2803 Register scratch = ToRegister(instr->temp());
2817 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
2818 HObjectAccess access = instr->hydrogen()->access();
2822 Register result = ToRegister(instr->result());
2823 if (instr->object()->IsConstantOperand()) {
2825 __ load_rax(ToExternalReference(LConstantOperand::cast(instr->object())));
2827 Register object = ToRegister(instr->object());
2833 Register object = ToRegister(instr->object());
2835 instr->hydrogen()->representation().IsDouble()) {
2836 XMMRegister result = ToDoubleRegister(instr->result());
2841 Register result = ToRegister(instr->result());
2850 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
2851 ASSERT(ToRegister(instr->context()).is(rsi));
2852 ASSERT(ToRegister(instr->object()).is(rax));
2853 ASSERT(ToRegister(instr->result()).is(rax));
2855 __ Move(rcx, instr->name());
2857 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2861 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
2862 Register function = ToRegister(instr->function());
2863 Register result = ToRegister(instr->result());
2867 DeoptimizeIf(not_equal, instr->environment());
2881 DeoptimizeIf(equal, instr->environment());
2902 void LCodeGen::DoLoadRoot(LLoadRoot* instr) {
2903 Register result = ToRegister(instr->result());
2904 __ LoadRoot(result, instr->index());
2909 LLoadExternalArrayPointer* instr) {
2910 Register result = ToRegister(instr->result());
2911 Register input = ToRegister(instr->object());
2917 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
2918 Register arguments = ToRegister(instr->arguments());
2919 Register result = ToRegister(instr->result());
2921 if (instr->length()->IsConstantOperand() &&
2922 instr->index()->IsConstantOperand()) {
2923 int32_t const_index = ToInteger32(LConstantOperand::cast(instr->index()));
2924 int32_t const_length = ToInteger32(LConstantOperand::cast(instr->length()));
2929 Register length = ToRegister(instr->length());
2932 if (instr->index()->IsRegister()) {
2933 __ subl(length, ToRegister(instr->index()));
2935 __ subl(length, ToOperand(instr->index()));
2944 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
2945 ElementsKind elements_kind = instr->elements_kind();
2946 LOperand* key = instr->key();
2954 if (instr->hydrogen()->IsDehoisted()) {
2961 instr->elements(),
2965 instr->additional_index()));
2968 XMMRegister result(ToDoubleRegister(instr->result()));
2972 __ movsd(ToDoubleRegister(instr->result()), operand);
2974 Register result(ToRegister(instr->result()));
2994 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
2996 DeoptimizeIf(negative, instr->environment());
3016 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
3017 XMMRegister result(ToDoubleRegister(instr->result()));
3018 LOperand* key = instr->key();
3025 if (instr->hydrogen()->IsDehoisted()) {
3032 if (instr->hydrogen()->RequiresHoleCheck()) {
3036 instr->elements(),
3040 instr->additional_index());
3042 DeoptimizeIf(equal, instr->environment());
3046 instr->elements(),
3050 instr->additional_index());
3055 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3056 Register result = ToRegister(instr->result());
3057 LOperand* key = instr->key();
3065 if (instr->hydrogen()->IsDehoisted()) {
3074 BuildFastArrayOperand(instr->elements(),
3078 instr->additional_index()));
3081 if (instr->hydrogen()->RequiresHoleCheck()) {
3082 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
3084 DeoptimizeIf(NegateCondition(smi), instr->environment());
3087 DeoptimizeIf(equal, instr->environment());
3093 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
3094 if (instr->is_external()) {
3095 DoLoadKeyedExternalArray(instr);
3096 } else if (instr->hydrogen()->representation().IsDouble()) {
3097 DoLoadKeyedFixedDoubleArray(instr);
3099 DoLoadKeyedFixedArray(instr);
3130 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
3131 ASSERT(ToRegister(instr->context()).is(rsi));
3132 ASSERT(ToRegister(instr->object()).is(rdx));
3133 ASSERT(ToRegister(instr->key()).is(rax));
3136 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3140 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
3141 Register result = ToRegister(instr->result());
3143 if (instr->hydrogen()->from_inlined()) {
3168 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
3169 Register result = ToRegister(instr->result());
3174 if (instr->elements()->IsRegister()) {
3175 __ cmpq(rbp, ToRegister(instr->elements()));
3177 __ cmpq(rbp, ToOperand(instr->elements()));
3193 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
3194 Register receiver = ToRegister(instr->receiver());
3195 Register function = ToRegister(instr->function());
3226 DeoptimizeIf(is_smi, instr->environment());
3228 DeoptimizeIf(below, instr->environment());
3243 void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
3244 Register receiver = ToRegister(instr->receiver());
3245 Register function = ToRegister(instr->function());
3246 Register length = ToRegister(instr->length());
3247 Register elements = ToRegister(instr->elements());
3250 ASSERT(ToRegister(instr->result()).is(rax));
3256 DeoptimizeIf(above, instr->environment());
3276 ASSERT(instr->HasPointerMap());
3277 LPointerMap* pointers = instr->pointer_map();
3286 void LCodeGen::DoPushArgument(LPushArgument* instr) {
3287 LOperand* argument = instr->value();
3292 void LCodeGen::DoDrop(LDrop* instr) {
3293 __ Drop(instr->count());
3297 void LCodeGen::DoThisFunction(LThisFunction* instr) {
3298 Register result = ToRegister(instr->result());
3303 void LCodeGen::DoContext(LContext* instr) {
3304 Register result = ToRegister(instr->result());
3314 void LCodeGen::DoOuterContext(LOuterContext* instr) {
3315 Register context = ToRegister(instr->context());
3316 Register result = ToRegister(instr->result());
3322 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
3323 ASSERT(ToRegister(instr->context()).is(rsi));
3325 __ Push(instr->hydrogen()->pairs());
3326 __ Push(Smi::FromInt(instr->hydrogen()->flags()));
3327 CallRuntime(Runtime::kDeclareGlobals, 3, instr);
3331 void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
3332 Register context = ToRegister(instr->context());
3333 Register result = ToRegister(instr->result());
3339 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
3340 Register global = ToRegister(instr->global());
3341 Register result = ToRegister(instr->result());
3349 LInstruction* instr,
3357 LPointerMap* pointers = instr->pointer_map();
3382 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0);
3395 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
3396 ASSERT(ToRegister(instr->result()).is(rax));
3397 CallKnownFunction(instr->hydrogen()->function(),
3398 instr->hydrogen()->formal_parameter_count(),
3399 instr->arity(),
3400 instr,
3406 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3407 Register input_reg = ToRegister(instr->value());
3410 DeoptimizeIf(not_equal, instr->environment());
3433 Runtime::kAllocateHeapNumber, 0, instr, instr->context());
3450 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
3451 Register input_reg = ToRegister(instr->value());
3456 DeoptimizeIf(negative, instr->environment());
3461 void LCodeGen::EmitSmiMathAbs(LMathAbs* instr) {
3462 Register input_reg = ToRegister(instr->value());
3467 DeoptimizeIf(negative, instr->environment());
3472 void LCodeGen::DoMathAbs(LMathAbs* instr) {
3476 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr)
3477 : LDeferredCode(codegen), instr_(instr) { }
3481 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
3486 ASSERT(instr->value()->Equals(instr->result()));
3487 Representation r = instr->hydrogen()->value()->representation();
3491 XMMRegister input_reg = ToDoubleRegister(instr->value());
3496 EmitIntegerMathAbs(instr);
3498 EmitSmiMathAbs(instr);
3501 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
3502 Register input_reg = ToRegister(instr->value());
3505 EmitSmiMathAbs(instr);
3511 void LCodeGen::DoMathFloor(LMathFloor* instr) {
3513 Register output_reg = ToRegister(instr->result());
3514 XMMRegister input_reg = ToDoubleRegister(instr->value());
3518 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3522 DeoptimizeIf(overflow, instr->environment());
3527 DeoptimizeIf(equal, instr->environment());
3533 DeoptimizeIf(parity_even, instr->environment());
3536 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3542 DeoptimizeIf(not_zero, instr->environment());
3552 DeoptimizeIf(equal, instr->environment());
3563 DeoptimizeIf(overflow, instr->environment());
3570 void LCodeGen::DoMathRound(LMathRound* instr) {
3572 Register output_reg = ToRegister(instr->result());
3573 XMMRegister input_reg = ToDoubleRegister(instr->value());
3590 DeoptimizeIf(equal, instr->environment());
3607 DeoptimizeIf(equal, instr->environment());
3621 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3625 DeoptimizeIf(negative, instr->environment());
3632 void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
3633 XMMRegister input_reg = ToDoubleRegister(instr->value());
3634 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
3639 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
3641 XMMRegister input_reg = ToDoubleRegister(instr->value());
3642 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
3671 void LCodeGen::DoPower(LPower* instr) {
3672 Representation exponent_type = instr->hydrogen()->right()->representation();
3677 ASSERT(!instr->right()->IsRegister() ||
3678 ToRegister(instr->right()).is(exponent));
3679 ASSERT(!instr->right()->IsDoubleRegister() ||
3680 ToDoubleRegister(instr->right()).is(xmm1));
3681 ASSERT(ToDoubleRegister(instr->left()).is(xmm2));
3682 ASSERT(ToDoubleRegister(instr->result()).is(xmm3));
3691 DeoptimizeIf(not_equal, instr->environment());
3706 void LCodeGen::DoMathExp(LMathExp* instr) {
3707 XMMRegister input = ToDoubleRegister(instr->value());
3708 XMMRegister result = ToDoubleRegister(instr->result());
3710 Register temp1 = ToRegister(instr->temp1());
3711 Register temp2 = ToRegister(instr->temp2());
3717 void LCodeGen::DoMathLog(LMathLog* instr) {
3718 ASSERT(instr->value()->Equals(instr->result()));
3719 XMMRegister input_reg = ToDoubleRegister(instr->value());
3750 void LCodeGen::DoMathTan(LMathTan* instr) {
3751 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
3757 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3761 void LCodeGen::DoMathCos(LMathCos* instr) {
3762 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
3768 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3772 void LCodeGen::DoMathSin(LMathSin* instr) {
3773 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
3779 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3783 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
3784 ASSERT(ToRegister(instr->context()).is(rsi));
3785 ASSERT(ToRegister(instr->function()).is(rdi));
3786 ASSERT(instr->HasPointerMap());
3788 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
3790 LPointerMap* pointers = instr->pointer_map();
3792 ParameterCount count(instr->arity());
3796 instr->hydrogen()->formal_parameter_count(),
3797 instr->arity(),
3798 instr,
3805 void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
3806 ASSERT(ToRegister(instr->context()).is(rsi));
3807 ASSERT(ToRegister(instr->key()).is(rcx));
3808 ASSERT(ToRegister(instr->result()).is(rax));
3810 int arity = instr->arity();
3813 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3817 void LCodeGen::DoCallNamed(LCallNamed* instr) {
3818 ASSERT(ToRegister(instr->context()).is(rsi));
3819 ASSERT(ToRegister(instr->result()).is(rax));
3821 int arity = instr->arity();
3825 __ Move(rcx, instr->name());
3826 CallCode(ic, mode, instr);
3830 void LCodeGen::DoCallFunction(LCallFunction* instr) {
3831 ASSERT(ToRegister(instr->context()).is(rsi));
3832 ASSERT(ToRegister(instr->function()).is(rdi));
3833 ASSERT(ToRegister(instr->result()).is(rax));
3835 int arity = instr->arity();
3837 if (instr->hydrogen()->IsTailCall()) {
3841 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3846 void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
3847 ASSERT(ToRegister(instr->context()).is(rsi));
3848 ASSERT(ToRegister(instr->result()).is(rax));
3849 int arity = instr->arity();
3853 __ Move(rcx, instr->name());
3854 CallCode(ic, mode, instr);
3858 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
3859 ASSERT(ToRegister(instr->result()).is(rax));
3860 CallKnownFunction(instr->hydrogen()->target(),
3861 instr->hydrogen()->formal_parameter_count(),
3862 instr->arity(),
3863 instr,
3869 void LCodeGen::DoCallNew(LCallNew* instr) {
3870 ASSERT(ToRegister(instr->context()).is(rsi));
3871 ASSERT(ToRegister(instr->constructor()).is(rdi));
3872 ASSERT(ToRegister(instr->result()).is(rax));
3874 __ Set(rax, instr->arity());
3879 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
3883 void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
3884 ASSERT(ToRegister(instr->context()).is(rsi));
3885 ASSERT(ToRegister(instr->constructor()).is(rdi));
3886 ASSERT(ToRegister(instr->result()).is(rax));
3888 __ Set(rax, instr->arity());
3889 __ Move(rbx, instr->hydrogen()->property_cell());
3890 ElementsKind kind = instr->hydrogen()->elements_kind();
3897 if (instr->arity() == 0) {
3899 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
3900 } else if (instr->arity() == 1) {
3913 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
3919 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
3923 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
3928 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
3929 ASSERT(ToRegister(instr->context()).is(rsi));
3930 CallRuntime(instr->function(), instr->arity(), instr, instr->save_doubles());
3934 void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) {
3935 Register function = ToRegister(instr->function());
3936 Register code_object = ToRegister(instr->code_object());
3942 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
3943 Register result = ToRegister(instr->result());
3944 Register base = ToRegister(instr->base_object());
3945 if (instr->offset()->IsConstantOperand()) {
3946 LConstantOperand* offset = LConstantOperand::cast(instr->offset());
3949 Register offset = ToRegister(instr->offset());
3955 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
3956 Representation representation = instr->representation();
3958 HObjectAccess access = instr->hydrogen()->access();
3962 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
3963 Register value = ToRegister(instr->value());
3964 if (instr->object()->IsConstantOperand()) {
3967 LConstantOperand* object = LConstantOperand::cast(instr->object());
3970 Register object = ToRegister(instr->object());
3976 Register object = ToRegister(instr->object());
3977 Handle<Map> transition = instr->transition();
3980 if (instr->value()->IsConstantOperand()) {
3981 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
3983 DeoptimizeIf(no_condition, instr->environment());
3987 if (instr->value()->IsConstantOperand()) {
3988 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
3990 DeoptimizeIf(no_condition, instr->environment());
3993 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
3994 Register value = ToRegister(instr->value());
3996 DeoptimizeIf(cc, instr->environment());
4002 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4003 XMMRegister value = ToDoubleRegister(instr->value());
4009 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) {
4012 Register temp = ToRegister(instr->temp());
4028 instr->hydrogen()->value()->IsHeapObject()
4033 write_register = ToRegister(instr->temp());
4037 if (instr->value()->IsConstantOperand()) {
4038 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4044 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4048 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4052 Register value = ToRegister(instr->value());
4056 if (instr->hydrogen()->NeedsWriteBarrier()) {
4057 Register value = ToRegister(instr->value());
4058 Register temp = access.IsInobject() ? ToRegister(instr->temp()) : object;
4071 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
4072 ASSERT(ToRegister(instr->context()).is(rsi));
4073 ASSERT(ToRegister(instr->object()).is(rdx));
4074 ASSERT(ToRegister(instr->value()).is(rax));
4076 __ Move(rcx, instr->hydrogen()->name());
4077 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
4080 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4096 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
4097 if (instr->hydrogen()->skip_check()) return;
4099 if (instr->length()->IsRegister()) {
4100 Register reg = ToRegister(instr->length());
4101 if (!instr->hydrogen()->length()->representation().IsSmi()) {
4104 if (instr->index()->IsConstantOperand()) {
4106 ToInteger32(LConstantOperand::cast(instr->index()));
4107 if (instr->hydrogen()->length()->representation().IsSmi()) {
4113 Register reg2 = ToRegister(instr->index());
4114 if (!instr->hydrogen()->index()->representation().IsSmi()) {
4120 Operand length = ToOperand(instr->length());
4121 if (instr->index()->IsConstantOperand()) {
4123 ToInteger32(LConstantOperand::cast(instr->index()));
4124 if (instr->hydrogen()->length()->representation().IsSmi()) {
4130 __ cmpq(length, ToRegister(instr->index()));
4134 instr->hydrogen()->allow_equality() ? below : below_equal;
4135 ApplyCheckIf(condition, instr);
4139 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4140 ElementsKind elements_kind = instr->elements_kind();
4141 LOperand* key = instr->key();
4149 if (instr->hydrogen()->IsDehoisted()) {
4156 instr->elements(),
4160 instr->additional_index()));
4163 XMMRegister value(ToDoubleRegister(instr->value()));
4167 __ movsd(operand, ToDoubleRegister(instr->value()));
4169 Register value(ToRegister(instr->value()));
4201 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
4202 XMMRegister value = ToDoubleRegister(instr->value());
4203 LOperand* key = instr->key();
4211 if (instr->hydrogen()->IsDehoisted()) {
4218 if (instr->NeedsCanonicalization()) {
4232 instr->elements(),
4236 instr->additional_index());
4242 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4243 Register elements = ToRegister(instr->elements());
4244 LOperand* key = instr->key();
4252 if (instr->hydrogen()->IsDehoisted()) {
4260 BuildFastArrayOperand(instr->elements(),
4264 instr->additional_index());
4265 if (instr->value()->IsRegister()) {
4266 __ movq(operand, ToRegister(instr->value()));
4268 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4278 if (instr->hydrogen()->NeedsWriteBarrier()) {
4279 ASSERT(instr->value()->IsRegister());
4280 Register value = ToRegister(instr->value());
4281 ASSERT(!instr->key()->IsConstantOperand());
4283 instr->hydrogen()->value()->IsHeapObject()
4298 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
4299 if (instr->is_external()) {
4300 DoStoreKeyedExternalArray(instr);
4301 } else if (instr->hydrogen()->value()->representation().IsDouble()) {
4302 DoStoreKeyedFixedDoubleArray(instr);
4304 DoStoreKeyedFixedArray(instr);
4309 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
4310 ASSERT(ToRegister(instr->context()).is(rsi));
4311 ASSERT(ToRegister(instr->object()).is(rdx));
4312 ASSERT(ToRegister(instr->key()).is(rcx));
4313 ASSERT(ToRegister(instr->value()).is(rax));
4315 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
4318 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4322 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
4323 Register object_reg = ToRegister(instr->object());
4325 Handle<Map> from_map = instr->original_map();
4326 Handle<Map> to_map = instr->transitioned_map();
4327 ElementsKind from_kind = instr->from_kind();
4328 ElementsKind to_kind = instr->to_kind();
4334 Register new_map_reg = ToRegister(instr->new_map_temp());
4338 ASSERT_NE(instr->temp(), NULL);
4340 ToRegister(instr->temp()), kDontSaveFPRegs);
4342 ASSERT(ToRegister(instr->context()).is(rsi));
4351 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4357 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
4358 Register object = ToRegister(instr->object());
4359 Register temp = ToRegister(instr->temp());
4362 DeoptimizeIf(equal, instr->environment());
4367 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4368 ASSERT(ToRegister(instr->context()).is(rsi));
4370 ASSERT(ToRegister(instr->left()).is(rdx));
4371 ASSERT(ToRegister(instr->right()).is(rax));
4372 NewStringAddStub stub(instr->hydrogen()->flags(),
4374 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4376 EmitPushTaggedOperand(instr->left());
4377 EmitPushTaggedOperand(instr->right());
4378 StringAddStub stub(instr->hydrogen()->flags());
4379 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4384 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
4387 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
4388 : LDeferredCode(codegen), instr_(instr) { }
4392 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4398 new(zone()) DeferredStringCharCodeAt(this, instr);
4401 ToRegister(instr->string()),
4402 ToRegister(instr->index()),
4403 ToRegister(instr->result()),
4409 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
4410 Register string = ToRegister(instr->string());
4411 Register result = ToRegister(instr->result());
4423 if (instr->index()->IsConstantOperand()) {
4424 int32_t const_index = ToInteger32(LConstantOperand::cast(instr->index()));
4427 Register index = ToRegister(instr->index());
4432 Runtime::kStringCharCodeAt, 2, instr, instr->context());
4439 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
4442 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
4443 : LDeferredCode(codegen), instr_(instr) { }
4447 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4453 new(zone()) DeferredStringCharFromCode(this, instr);
4455 ASSERT(instr->hydrogen()->value()->representation().IsInteger32());
4456 Register char_code = ToRegister(instr->char_code());
4457 Register result = ToRegister(instr->result());
4473 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
4474 Register char_code = ToRegister(instr->char_code());
4475 Register result = ToRegister(instr->result());
4485 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context());
4490 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4491 LOperand* input = instr->value();
4493 LOperand* output = instr->result();
4503 void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) {
4504 LOperand* input = instr->value();
4506 LOperand* output = instr->result();
4508 if (!instr->hydrogen()->value()->HasRange() ||
4509 !instr->hydrogen()->value()->range()->IsInSmiRange()) {
4510 DeoptimizeIf(overflow, instr->environment());
4515 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4516 LOperand* input = instr->value();
4517 LOperand* output = instr->result();
4518 LOperand* temp = instr->temp();
4526 void LCodeGen::DoUint32ToSmi(LUint32ToSmi* instr) {
4527 LOperand* input = instr->value();
4529 LOperand* output = instr->result();
4530 if (!instr->hydrogen()->value()->HasRange() ||
4531 !instr->hydrogen()->value()->range()->IsInSmiRange() ||
4532 instr->hydrogen()->value()->range()->upper() == kMaxInt) {
4536 DeoptimizeIf(not_zero, instr->environment());
4542 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4543 LOperand* input = instr->value();
4544 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4551 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4554 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
4555 : LDeferredCode(codegen), instr_(instr) { }
4559 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4564 LOperand* input = instr->value();
4565 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4568 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4576 void LCodeGen::DoDeferredNumberTagU(LNumberTagU* instr) {
4578 Register reg = ToRegister(instr->value());
4580 XMMRegister temp_xmm = ToDoubleRegister(instr->temp());
4613 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4625 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
4628 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4629 : LDeferredCode(codegen), instr_(instr) { }
4633 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4638 XMMRegister input_reg = ToDoubleRegister(instr->value());
4639 Register reg = ToRegister(instr->result());
4640 Register tmp = ToRegister(instr->temp());
4642 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4653 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
4657 Register reg = ToRegister(instr->result());
4670 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4677 void LCodeGen::DoSmiTag(LSmiTag* instr) {
4678 ASSERT(instr->value()->Equals(instr->result()));
4679 Register input = ToRegister(instr->value());
4680 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
4685 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
4686 ASSERT(instr->value()->Equals(instr->result()));
4687 Register input = ToRegister(instr->value());
4688 if (instr->needs_check()) {
4690 DeoptimizeIf(NegateCondition(is_smi), instr->environment());
4758 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) {
4759 Register input_reg = ToRegister(instr->value());
4761 if (instr->truncating()) {
4788 DeoptimizeIf(not_equal, instr->environment());
4793 XMMRegister xmm_temp = ToDoubleRegister(instr->temp());
4795 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);
4799 DeoptimizeIf(no_condition, instr->environment());
4804 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
4807 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
4808 : LDeferredCode(codegen), instr_(instr) { }
4812 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4817 LOperand* input = instr->value();
4819 ASSERT(input->Equals(instr->result()));
4822 if (instr->hydrogen()->value()->representation().IsSmi()) {
4825 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
4833 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
4834 LOperand* input = instr->value();
4836 LOperand* result = instr->result();
4842 HValue* value = instr->hydrogen()->value();
4847 instr->hydrogen()->can_convert_undefined_to_nan(),
4848 instr->hydrogen()->deoptimize_on_minus_zero(),
4849 instr->environment(),
4854 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
4855 LOperand* input = instr->value();
4857 LOperand* result = instr->result();
4863 if (instr->truncating()) {
4869 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);
4873 DeoptimizeIf(no_condition, instr->environment());
4879 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
4880 LOperand* input = instr->value();
4882 LOperand* result = instr->result();
4891 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);
4895 DeoptimizeIf(no_condition, instr->environment());
4899 DeoptimizeIf(overflow, instr->environment());
4903 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
4904 LOperand* input = instr->value();
4906 DeoptimizeIf(NegateCondition(cc), instr->environment());
4910 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
4911 if (!instr->hydrogen()->value()->IsHeapObject()) {
4912 LOperand* input = instr->value();
4914 DeoptimizeIf(cc, instr->environment());
4919 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
4920 Register input = ToRegister(instr->value());
4924 if (instr->hydrogen()->is_interval_check()) {
4927 instr->hydrogen()->GetCheckInterval(&first, &last);
4934 DeoptimizeIf(not_equal, instr->environment());
4936 DeoptimizeIf(below, instr->environment());
4941 DeoptimizeIf(above, instr->environment());
4947 instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
4953 DeoptimizeIf(tag == 0 ? not_zero : zero, instr->environment());
4959 DeoptimizeIf(not_equal, instr->environment());
4965 void LCodeGen::DoCheckValue(LCheckValue* instr) {
4966 Register reg = ToRegister(instr->value());
4967 __ Cmp(reg, instr->hydrogen()->object().handle());
4968 DeoptimizeIf(not_equal, instr->environment());
4972 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
4979 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt);
4983 DeoptimizeIf(zero, instr->environment());
4987 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
4990 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object)
4991 : LDeferredCode(codegen), instr_(instr), object_(object) {
4998 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5005 if (instr->hydrogen()->CanOmitMapChecks()) return;
5007 LOperand* input = instr->value();
5012 if (instr->hydrogen()->has_migration_target()) {
5013 deferred = new(zone()) DeferredCheckMaps(this, instr, reg);
5017 UniqueSet<Map> map_set = instr->hydrogen()->map_set();
5027 if (instr->hydrogen()->has_migration_target()) {
5030 DeoptimizeIf(not_equal, instr->environment());
5037 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
5038 XMMRegister value_reg = ToDoubleRegister(instr->unclamped());
5040 Register result_reg = ToRegister(instr->result());
5045 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
5046 ASSERT(instr->unclamped()->Equals(instr->result()));
5047 Register value_reg = ToRegister(instr->result());
5052 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
5053 ASSERT(instr->unclamped()->Equals(instr->result()));
5054 Register input_reg = ToRegister(instr->unclamped());
5055 XMMRegister temp_xmm_reg = ToDoubleRegister(instr->temp_xmm());
5069 DeoptimizeIf(not_equal, instr->environment());
5088 void LCodeGen::DoAllocate(LAllocate* instr) {
5091 DeferredAllocate(LCodeGen* codegen, LAllocate* instr)
5092 : LDeferredCode(codegen), instr_(instr) { }
5096 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5102 new(zone()) DeferredAllocate(this, instr);
5104 Register result = ToRegister(instr->result());
5105 Register temp = ToRegister(instr->temp());
5109 if (instr->hydrogen()->MustAllocateDoubleAligned()) {
5112 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5113 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation());
5114 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5116 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5117 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5121 if (instr->size()->IsConstantOperand()) {
5122 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5129 Register size = ToRegister(instr->size());
5135 if (instr->hydrogen()->MustPrefillWithFiller()) {
5136 if (instr->size()->IsConstantOperand()) {
5137 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5140 temp = ToRegister(instr->size());
5154 void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
5155 Register result = ToRegister(instr->result());
5163 if (instr->size()->IsRegister()) {
5164 Register size = ToRegister(instr->size());
5169 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5174 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5175 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation());
5176 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5178 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5179 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5187 Runtime::kAllocateInTargetSpace, 2, instr, instr->context());
5192 void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
5193 ASSERT(ToRegister(instr->value()).is(rax));
5195 CallRuntime(Runtime::kToFastProperties, 1, instr);
5199 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
5200 ASSERT(ToRegister(instr->context()).is(rsi));
5207 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
5208 __ Move(rcx, instr->hydrogen()->literals());
5216 __ Push(Smi::FromInt(instr->hydrogen()->literal_index()));
5217 __ Push(instr->hydrogen()->pattern());
5218 __ Push(instr->hydrogen()->flags());
5219 CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr);
5231 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr);
5250 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
5251 ASSERT(ToRegister(instr->context()).is(rsi));
5254 bool pretenure = instr->hydrogen()->pretenure();
5255 if (!pretenure && instr->hydrogen()->has_no_literals()) {
5256 FastNewClosureStub stub(instr->hydrogen()->language_mode(),
5257 instr->hydrogen()->is_generator());
5258 __ Move(rbx, instr->hydrogen()->shared_info());
5259 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
5262 __ Push(instr->hydrogen()->shared_info());
5265 CallRuntime(Runtime::kNewClosure, 3, instr);
5270 void LCodeGen::DoTypeof(LTypeof* instr) {
5271 ASSERT(ToRegister(instr->context()).is(rsi));
5272 LOperand* input = instr->value();
5274 CallRuntime(Runtime::kTypeof, 1, instr);
5290 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
5291 Register input = ToRegister(instr->value());
5292 Condition final_branch_condition = EmitTypeofIs(instr, input);
5294 EmitBranch(instr, final_branch_condition);
5299 Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) {
5300 Label* true_label = instr->TrueLabel(chunk_);
5301 Label* false_label = instr->FalseLabel(chunk_);
5302 Handle<String> type_name = instr->type_literal();
5303 int left_block = instr->TrueDestination(chunk_);
5304 int right_block = instr->FalseDestination(chunk_);
5383 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
5384 Register temp = ToRegister(instr->temp());
5387 EmitBranch(instr, equal);
5421 void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
5424 ASSERT(instr->HasEnvironment());
5425 LEnvironment* env = instr->environment();
5431 void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
5432 Deoptimizer::BailoutType type = instr->hydrogen()->type();
5441 Comment(";;; deoptimize: %s", instr->hydrogen()->reason());
5442 DeoptimizeIf(no_condition, instr->environment(), type);
5446 void LCodeGen::DoDummy(LDummy* instr) {
5451 void LCodeGen::DoDummyUse(LDummyUse* instr) {
5456 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
5460 RecordSafepointWithLazyDeopt(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0);
5461 ASSERT(instr->HasEnvironment());
5462 LEnvironment* env = instr->environment();
5467 void LCodeGen::DoStackCheck(LStackCheck* instr) {
5470 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
5471 : LDeferredCode(codegen), instr_(instr) { }
5475 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5480 ASSERT(instr->HasEnvironment());
5481 LEnvironment* env = instr->environment();
5484 if (instr->hydrogen()->is_function_entry()) {
5490 ASSERT(instr->context()->IsRegister());
5491 ASSERT(ToRegister(instr->context()).is(rsi));
5494 instr);
5501 ASSERT(instr->hydrogen()->is_backwards_branch());
5504 new(zone()) DeferredStackCheck(this, instr);
5509 __ bind(instr->done_label());
5510 deferred_stack_check->SetExit(instr->done_label());
5519 void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
5523 LEnvironment* environment = instr->environment();
5534 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
5535 ASSERT(ToRegister(instr->context()).is(rsi));
5537 DeoptimizeIf(equal, instr->environment());
5542 DeoptimizeIf(equal, instr->environment());
5545 DeoptimizeIf(cc, instr->environment());
5549 DeoptimizeIf(below_equal, instr->environment());
5560 CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr);
5564 DeoptimizeIf(not_equal, instr->environment());
5569 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) {
5570 Register map = ToRegister(instr->map());
5571 Register result = ToRegister(instr->result());
5583 FieldOperand(result, FixedArray::SizeFor(instr->idx())));
5586 DeoptimizeIf(cc, instr->environment());
5590 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
5591 Register object = ToRegister(instr->value());
5592 __ cmpq(ToRegister(instr->map()),
5594 DeoptimizeIf(not_equal, instr->environment());
5598 void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
5599 Register object = ToRegister(instr->object());
5600 Register index = ToRegister(instr->index());