Lines Matching defs:instr

383                         LInstruction* instr) {
384 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT);
390 LInstruction* instr,
392 DCHECK(instr != NULL);
396 RecordSafepointWithLazyDeopt(instr, safepoint_mode);
407 void LCodeGen::DoCallFunction(LCallFunction* instr) {
408 DCHECK(ToRegister(instr->context()).is(cp));
409 DCHECK(ToRegister(instr->function()).Is(x1));
410 DCHECK(ToRegister(instr->result()).Is(x0));
412 int arity = instr->arity();
413 CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
414 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
419 void LCodeGen::DoCallNew(LCallNew* instr) {
420 DCHECK(ToRegister(instr->context()).is(cp));
421 DCHECK(instr->IsMarkedAsCall());
422 DCHECK(ToRegister(instr->constructor()).is(x1));
424 __ Mov(x0, instr->arity());
429 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
432 DCHECK(ToRegister(instr->result()).is(x0));
436 void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
437 DCHECK(instr->IsMarkedAsCall());
438 DCHECK(ToRegister(instr->context()).is(cp));
439 DCHECK(ToRegister(instr->constructor()).is(x1));
441 __ Mov(x0, Operand(instr->arity()));
444 ElementsKind kind = instr->hydrogen()->elements_kind();
450 if (instr->arity() == 0) {
452 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
453 } else if (instr->arity() == 1) {
466 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
472 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
476 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
480 DCHECK(ToRegister(instr->result()).is(x0));
486 LInstruction* instr,
488 DCHECK(instr != NULL);
492 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
514 LInstruction* instr,
519 instr->pointer_map(), argc, Safepoint::kNoLazyDeopt);
530 void LCodeGen::RecordSafepointWithLazyDeopt(LInstruction* instr,
533 RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt);
537 instr->pointer_map(), 0, Safepoint::kLazyDeopt);
762 void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
763 if (instr->IsCall()) {
766 if (!instr->IsLazyBailout() && !instr->IsGap()) {
786 code->instr()->hydrogen_value()->id(),
787 code->instr()->Mnemonic());
992 LInstruction* instr, const char* detail, BranchType branch_type,
994 LEnvironment* environment = instr->environment();
1043 Deoptimizer::Reason reason(instr->hydrogen_value()->position().raw(),
1044 instr->Mnemonic(), detail);
1066 void LCodeGen::Deoptimize(LInstruction* instr,
1069 DeoptimizeBranch(instr, detail, always, NoReg, -1, override_bailout_type);
1073 void LCodeGen::DeoptimizeIf(Condition cond, LInstruction* instr,
1075 DeoptimizeBranch(instr, detail, static_cast<BranchType>(cond));
1079 void LCodeGen::DeoptimizeIfZero(Register rt, LInstruction* instr,
1081 DeoptimizeBranch(instr, detail, reg_zero, rt);
1085 void LCodeGen::DeoptimizeIfNotZero(Register rt, LInstruction* instr,
1087 DeoptimizeBranch(instr, detail, reg_not_zero, rt);
1091 void LCodeGen::DeoptimizeIfNegative(Register rt, LInstruction* instr,
1094 DeoptimizeIfBitSet(rt, sign_bit, instr, detail);
1098 void LCodeGen::DeoptimizeIfSmi(Register rt, LInstruction* instr,
1100 DeoptimizeIfBitClear(rt, MaskToBit(kSmiTagMask), instr, detail);
1104 void LCodeGen::DeoptimizeIfNotSmi(Register rt, LInstruction* instr,
1106 DeoptimizeIfBitSet(rt, MaskToBit(kSmiTagMask), instr, detail);
1111 LInstruction* instr, const char* detail) {
1113 DeoptimizeIf(eq, instr, detail);
1118 LInstruction* instr, const char* detail) {
1120 DeoptimizeIf(ne, instr, detail);
1124 void LCodeGen::DeoptimizeIfMinusZero(DoubleRegister input, LInstruction* instr,
1127 DeoptimizeIf(vs, instr, detail);
1131 void LCodeGen::DeoptimizeIfNotHeapNumber(Register object, LInstruction* instr) {
1133 DeoptimizeIf(ne, instr, "not heap number");
1137 void LCodeGen::DeoptimizeIfBitSet(Register rt, int bit, LInstruction* instr,
1139 DeoptimizeBranch(instr, detail, reg_bit_set, rt, bit);
1143 void LCodeGen::DeoptimizeIfBitClear(Register rt, int bit, LInstruction* instr,
1145 DeoptimizeBranch(instr, detail, reg_bit_clear, rt, bit);
1375 void LCodeGen::EmitBranchGeneric(InstrType instr,
1377 int left_block = instr->TrueDestination(chunk_);
1378 int right_block = instr->FalseDestination(chunk_);
1396 void LCodeGen::EmitBranch(InstrType instr, Condition condition) {
1399 EmitBranchGeneric(instr, branch);
1404 void LCodeGen::EmitCompareAndBranch(InstrType instr,
1410 EmitBranchGeneric(instr, branch);
1415 void LCodeGen::EmitTestAndBranch(InstrType instr,
1421 EmitBranchGeneric(instr, branch);
1426 void LCodeGen::EmitBranchIfNonZeroNumber(InstrType instr,
1430 EmitBranchGeneric(instr, branch);
1435 void LCodeGen::EmitBranchIfHeapNumber(InstrType instr,
1438 EmitBranchGeneric(instr, branch);
1443 void LCodeGen::EmitBranchIfRoot(InstrType instr,
1447 EmitBranchGeneric(instr, branch);
1464 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
1465 Register arguments = ToRegister(instr->arguments());
1466 Register result = ToRegister(instr->result());
1473 if (instr->length()->IsConstantOperand() &&
1474 instr->index()->IsConstantOperand()) {
1475 int index = ToInteger32(LConstantOperand::cast(instr->index()));
1476 int length = ToInteger32(LConstantOperand::cast(instr->length()));
1479 } else if (instr->index()->IsConstantOperand()) {
1480 Register length = ToRegister32(instr->length());
1481 int index = ToInteger32(LConstantOperand::cast(instr->index()));
1490 Register length = ToRegister32(instr->length());
1491 Operand index = ToOperand32(instr->index());
1499 void LCodeGen::DoAddE(LAddE* instr) {
1500 Register result = ToRegister(instr->result());
1501 Register left = ToRegister(instr->left());
1502 Operand right = (instr->right()->IsConstantOperand())
1503 ? ToInteger32(LConstantOperand::cast(instr->right()))
1504 : Operand(ToRegister32(instr->right()), SXTW);
1506 DCHECK(!instr->hydrogen()->CheckFlag(HValue::kCanOverflow));
1511 void LCodeGen::DoAddI(LAddI* instr) {
1512 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1513 Register result = ToRegister32(instr->result());
1514 Register left = ToRegister32(instr->left());
1515 Operand right = ToShiftedRightOperand32(instr->right(), instr);
1519 DeoptimizeIf(vs, instr);
1526 void LCodeGen::DoAddS(LAddS* instr) {
1527 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1528 Register result = ToRegister(instr->result());
1529 Register left = ToRegister(instr->left());
1530 Operand right = ToOperand(instr->right());
1533 DeoptimizeIf(vs, instr);
1540 void LCodeGen::DoAllocate(LAllocate* instr) {
1543 DeferredAllocate(LCodeGen* codegen, LAllocate* instr)
1544 : LDeferredCode(codegen), instr_(instr) { }
1546 virtual LInstruction* instr() { return instr_; }
1551 DeferredAllocate* deferred = new(zone()) DeferredAllocate(this, instr);
1553 Register result = ToRegister(instr->result());
1554 Register temp1 = ToRegister(instr->temp1());
1555 Register temp2 = ToRegister(instr->temp2());
1559 if (instr->hydrogen()->MustAllocateDoubleAligned()) {
1563 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
1564 DCHECK(!instr->hydrogen()->IsOldDataSpaceAllocation());
1565 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
1567 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
1568 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
1572 if (instr->size()->IsConstantOperand()) {
1573 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
1580 Register size = ToRegister32(instr->size());
1587 if (instr->hydrogen()->MustPrefillWithFiller()) {
1590 Register untagged_result = ToRegister(instr->temp3());
1592 if (instr->size()->IsConstantOperand()) {
1593 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
1596 __ Lsr(filler_count.W(), ToRegister32(instr->size()), kPointerSizeLog2);
1603 DCHECK(instr->temp3() == NULL);
1608 void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
1612 __ Mov(ToRegister(instr->result()), Smi::FromInt(0));
1617 if (instr->size()->IsConstantOperand()) {
1618 __ Mov(size, ToSmi(LConstantOperand::cast(instr->size())));
1620 __ SmiTag(size, ToRegister32(instr->size()).X());
1623 instr->hydrogen()->MustAllocateDoubleAligned());
1624 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
1625 DCHECK(!instr->hydrogen()->IsOldDataSpaceAllocation());
1626 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
1628 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
1629 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
1638 Runtime::kAllocateInTargetSpace, 2, instr, instr->context());
1639 __ StoreToSafepointRegisterSlot(x0, ToRegister(instr->result()));
1643 void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
1644 Register receiver = ToRegister(instr->receiver());
1645 Register function = ToRegister(instr->function());
1646 Register length = ToRegister32(instr->length());
1648 Register elements = ToRegister(instr->elements());
1652 DCHECK(ToRegister(instr->result()).Is(x0));
1653 DCHECK(instr->IsMarkedAsCall());
1659 DeoptimizeIf(hi, instr);
1682 DCHECK(instr->HasPointerMap());
1683 LPointerMap* pointers = instr->pointer_map();
1692 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
1697 Register result = ToRegister(instr->result());
1699 if (instr->hydrogen()->from_inlined()) {
1711 DCHECK(instr->temp() != NULL);
1712 Register previous_fp = ToRegister(instr->temp());
1724 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
1725 Register elements = ToRegister(instr->elements());
1726 Register result = ToRegister32(instr->result());
1745 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1746 DoubleRegister left = ToDoubleRegister(instr->left());
1747 DoubleRegister right = ToDoubleRegister(instr->right());
1748 DoubleRegister result = ToDoubleRegister(instr->result());
1750 switch (instr->op()) {
1780 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
1781 DCHECK(ToRegister(instr->context()).is(cp));
1782 DCHECK(ToRegister(instr->left()).is(x1));
1783 DCHECK(ToRegister(instr->right()).is(x0));
1784 DCHECK(ToRegister(instr->result()).is(x0));
1787 CodeFactory::BinaryOpIC(isolate(), instr->op(), NO_OVERWRITE).code();
1788 CallCode(code, RelocInfo::CODE_TARGET, instr);
1792 void LCodeGen::DoBitI(LBitI* instr) {
1793 Register result = ToRegister32(instr->result());
1794 Register left = ToRegister32(instr->left());
1795 Operand right = ToShiftedRightOperand32(instr->right(), instr);
1797 switch (instr->op()) {
1808 void LCodeGen::DoBitS(LBitS* instr) {
1809 Register result = ToRegister(instr->result());
1810 Register left = ToRegister(instr->left());
1811 Operand right = ToOperand(instr->right());
1813 switch (instr->op()) {
1824 void LCodeGen::DoBoundsCheck(LBoundsCheck *instr) {
1825 Condition cond = instr->hydrogen()->allow_equality() ? hi : hs;
1826 DCHECK(instr->hydrogen()->index()->representation().IsInteger32());
1827 DCHECK(instr->hydrogen()->length()->representation().IsInteger32());
1828 if (instr->index()->IsConstantOperand()) {
1829 Operand index = ToOperand32(instr->index());
1830 Register length = ToRegister32(instr->length());
1834 Register index = ToRegister32(instr->index());
1835 Operand length = ToOperand32(instr->length());
1838 if (FLAG_debug_code && instr->hydrogen()->skip_check()) {
1841 DeoptimizeIf(cond, instr);
1846 void LCodeGen::DoBranch(LBranch* instr) {
1847 Representation r = instr->hydrogen()->value()->representation();
1848 Label* true_label = instr->TrueLabel(chunk_);
1849 Label* false_label = instr->FalseLabel(chunk_);
1853 EmitCompareAndBranch(instr, ne, ToRegister32(instr->value()), 0);
1857 EmitCompareAndBranch(instr, ne, ToRegister(instr->value()), 0);
1859 DoubleRegister value = ToDoubleRegister(instr->value());
1861 EmitBranchIfNonZeroNumber(instr, value, double_scratch());
1864 Register value = ToRegister(instr->value());
1865 HType type = instr->hydrogen()->value()->type();
1870 EmitBranch(instr, eq);
1873 EmitCompareAndBranch(instr, ne, value, Smi::FromInt(0));
1876 EmitGoto(instr->TrueDestination(chunk()));
1882 EmitBranchIfNonZeroNumber(instr, double_scratch(), double_scratch());
1885 Register temp = ToRegister(instr->temp1());
1887 EmitCompareAndBranch(instr, ne, temp, 0);
1889 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
1920 DeoptimizeIfSmi(value, instr);
1927 DCHECK((instr->temp1() != NULL) && (instr->temp2() != NULL));
1928 map = ToRegister(instr->temp1());
1929 scratch = ToRegister(instr->temp2());
1981 Deoptimize(instr);
1991 LInstruction* instr,
2002 LPointerMap* pointers = instr->pointer_map();
2033 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
2044 LTailCallThroughMegamorphicCache* instr) {
2045 Register receiver = ToRegister(instr->receiver());
2046 Register name = ToRegister(instr->name());
2061 isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(),
2071 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
2072 DCHECK(instr->IsMarkedAsCall());
2073 DCHECK(ToRegister(instr->result()).Is(x0));
2075 LPointerMap* pointers = instr->pointer_map();
2078 if (instr->target()->IsConstantOperand()) {
2079 LConstantOperand* target = LConstantOperand::cast(instr->target());
2087 DCHECK(instr->target()->IsRegister());
2088 Register target = ToRegister(instr->target());
2098 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) {
2099 DCHECK(instr->IsMarkedAsCall());
2100 DCHECK(ToRegister(instr->function()).is(x1));
2102 if (instr->hydrogen()->pass_argument_count()) {
2103 __ Mov(x0, Operand(instr->arity()));
2113 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
2118 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
2119 CallRuntime(instr->function(), instr->arity(), instr);
2124 void LCodeGen::DoCallStub(LCallStub* instr) {
2125 DCHECK(ToRegister(instr->context()).is(cp));
2126 DCHECK(ToRegister(instr->result()).is(x0));
2127 switch (instr->hydrogen()->major_key()) {
2130 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2135 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2140 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2150 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
2155 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
2156 Register temp = ToRegister(instr->temp());
2163 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt);
2166 DeoptimizeIfSmi(temp, instr);
2170 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
2173 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object)
2174 : LDeferredCode(codegen), instr_(instr), object_(object) {
2181 virtual LInstruction* instr() { return instr_; }
2188 if (instr->hydrogen()->IsStabilityCheck()) {
2189 const UniqueSet<Map>* maps = instr->hydrogen()->maps();
2196 Register object = ToRegister(instr->value());
2197 Register map_reg = ToRegister(instr->temp());
2202 if (instr->hydrogen()->HasMigrationTarget()) {
2203 deferred = new(zone()) DeferredCheckMaps(this, instr, object);
2207 const UniqueSet<Map>* maps = instr->hydrogen()->maps();
2218 if (instr->hydrogen()->HasMigrationTarget()) {
2221 DeoptimizeIf(ne, instr);
2228 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
2229 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
2230 DeoptimizeIfSmi(ToRegister(instr->value()), instr);
2235 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
2236 Register value = ToRegister(instr->value());
2237 DCHECK(!instr->result() || ToRegister(instr->result()).Is(value));
2238 DeoptimizeIfNotSmi(value, instr);
2242 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
2243 Register input = ToRegister(instr->value());
2244 Register scratch = ToRegister(instr->temp());
2249 if (instr->hydrogen()->is_interval_check()) {
2251 instr->hydrogen()->GetCheckInterval(&first, &last);
2256 DeoptimizeIf(ne, instr);
2259 DeoptimizeIf(lo, instr);
2264 DeoptimizeIf(hi, instr);
2269 instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
2274 DeoptimizeIfBitSet(scratch, MaskToBit(mask), instr);
2276 DeoptimizeIfBitClear(scratch, MaskToBit(mask), instr);
2285 DeoptimizeIf(ne, instr);
2291 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
2292 DoubleRegister input = ToDoubleRegister(instr->unclamped());
2293 Register result = ToRegister32(instr->result());
2298 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
2299 Register input = ToRegister32(instr->unclamped());
2300 Register result = ToRegister32(instr->result());
2305 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
2306 Register input = ToRegister(instr->unclamped());
2307 Register result = ToRegister32(instr->result());
2324 DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex, instr);
2331 DoubleRegister dbl_scratch2 = ToDoubleRegister(instr->temp1());
2339 void LCodeGen::DoDoubleBits(LDoubleBits* instr) {
2340 DoubleRegister value_reg = ToDoubleRegister(instr->value());
2341 Register result_reg = ToRegister(instr->result());
2342 if (instr->hydrogen()->bits() == HDoubleBits::HIGH) {
2351 void LCodeGen::DoConstructDouble(LConstructDouble* instr) {
2352 Register hi_reg = ToRegister(instr->hi());
2353 Register lo_reg = ToRegister(instr->lo());
2354 DoubleRegister result_reg = ToDoubleRegister(instr->result());
2363 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2364 Handle<String> class_name = instr->hydrogen()->class_name();
2365 Label* true_label = instr->TrueLabel(chunk_);
2366 Label* false_label = instr->FalseLabel(chunk_);
2367 Register input = ToRegister(instr->value());
2368 Register scratch1 = ToRegister(instr->temp1());
2369 Register scratch2 = ToRegister(instr->temp2());
2420 EmitCompareAndBranch(instr, eq, scratch1, Operand(class_name));
2424 void LCodeGen::DoCmpHoleAndBranchD(LCmpHoleAndBranchD* instr) {
2425 DCHECK(instr->hydrogen()->representation().IsDouble());
2426 FPRegister object = ToDoubleRegister(instr->object());
2427 Register temp = ToRegister(instr->temp());
2432 __ B(vc, instr->FalseLabel(chunk_));
2436 EmitCompareAndBranch(instr, eq, temp, kHoleNanInt64);
2440 void LCodeGen::DoCmpHoleAndBranchT(LCmpHoleAndBranchT* instr) {
2441 DCHECK(instr->hydrogen()->representation().IsTagged());
2442 Register object = ToRegister(instr->object());
2444 EmitBranchIfRoot(instr, object, Heap::kTheHoleValueRootIndex);
2448 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
2449 Register value = ToRegister(instr->value());
2450 Register map = ToRegister(instr->temp());
2453 EmitCompareAndBranch(instr, eq, map, Operand(instr->map()));
2457 void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
2458 Representation rep = instr->hydrogen()->value()->representation();
2460 Register scratch = ToRegister(instr->temp());
2463 __ JumpIfMinusZero(ToDoubleRegister(instr->value()),
2464 instr->TrueLabel(chunk()));
2466 Register value = ToRegister(instr->value());
2467 __ JumpIfNotHeapNumber(value, instr->FalseLabel(chunk()), DO_SMI_CHECK);
2469 __ JumpIfMinusZero(scratch, instr->TrueLabel(chunk()));
2471 EmitGoto(instr->FalseDestination(chunk()));
2475 void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) {
2476 LOperand* left = instr->left();
2477 LOperand* right = instr->right();
2479 instr->hydrogen()->left()->CheckFlag(HInstruction::kUint32) ||
2480 instr->hydrogen()->right()->CheckFlag(HInstruction::kUint32);
2481 Condition cond = TokenToCondition(instr->op(), is_unsigned);
2487 int next_block = EvalComparison(instr->op(), left_val, right_val) ?
2488 instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_);
2491 if (instr->is_double()) {
2496 __ B(vs, instr->FalseLabel(chunk_));
2497 EmitBranch(instr, cond);
2499 if (instr->hydrogen_value()->representation().IsInteger32()) {
2501 EmitCompareAndBranch(instr, cond, ToRegister32(left),
2505 EmitCompareAndBranch(instr, CommuteCondition(cond),
2509 DCHECK(instr->hydrogen_value()->representation().IsSmi());
2512 EmitCompareAndBranch(instr,
2519 EmitCompareAndBranch(instr,
2524 EmitCompareAndBranch(instr,
2535 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
2536 Register left = ToRegister(instr->left());
2537 Register right = ToRegister(instr->right());
2538 EmitCompareAndBranch(instr, eq, left, right);
2542 void LCodeGen::DoCmpT(LCmpT* instr) {
2543 DCHECK(ToRegister(instr->context()).is(cp));
2544 Token::Value op = instr->op();
2547 DCHECK(ToRegister(instr->left()).Is(x1));
2548 DCHECK(ToRegister(instr->right()).Is(x0));
2550 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2556 DCHECK(instr->IsMarkedAsCall());
2559 __ Csel(ToRegister(instr->result()), x1, x2, cond);
2563 void LCodeGen::DoConstantD(LConstantD* instr) {
2564 DCHECK(instr->result()->IsDoubleRegister());
2565 DoubleRegister result = ToDoubleRegister(instr->result());
2566 if (instr->value() == 0) {
2567 if (copysign(1.0, instr->value()) == 1.0) {
2573 __ Fmov(result, instr->value());
2578 void LCodeGen::DoConstantE(LConstantE* instr) {
2579 __ Mov(ToRegister(instr->result()), Operand(instr->value()));
2583 void LCodeGen::DoConstantI(LConstantI* instr) {
2584 DCHECK(is_int32(instr->value()));
2587 __ Mov(ToRegister32(instr->result()), static_cast<uint32_t>(instr->value()));
2591 void LCodeGen::DoConstantS(LConstantS* instr) {
2592 __ Mov(ToRegister(instr->result()), Operand(instr->value()));
2596 void LCodeGen::DoConstantT(LConstantT* instr) {
2597 Handle<Object> object = instr->value(isolate());
2599 __ LoadObject(ToRegister(instr->result()), object);
2603 void LCodeGen::DoContext(LContext* instr) {
2605 Register result = ToRegister(instr->result());
2615 void LCodeGen::DoCheckValue(LCheckValue* instr) {
2616 Register reg = ToRegister(instr->value());
2617 Handle<HeapObject> object = instr->hydrogen()->object().handle();
2629 DeoptimizeIf(ne, instr);
2633 void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
2635 DCHECK(instr->HasEnvironment());
2636 LEnvironment* env = instr->environment();
2642 void LCodeGen::DoDateField(LDateField* instr) {
2643 Register object = ToRegister(instr->date());
2644 Register result = ToRegister(instr->result());
2647 Smi* index = instr->index();
2651 DCHECK(instr->IsMarkedAsCall());
2653 DeoptimizeIfSmi(object, instr);
2655 DeoptimizeIf(ne, instr);
2681 void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
2682 Deoptimizer::BailoutType type = instr->hydrogen()->type();
2691 Deoptimize(instr, &type, instr->hydrogen()->reason());
2695 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
2696 Register dividend = ToRegister32(instr->dividend());
2697 int32_t divisor = instr->divisor();
2698 Register result = ToRegister32(instr->result());
2703 HDiv* hdiv = instr->hydrogen();
2705 DeoptimizeIfZero(dividend, instr);
2712 DeoptimizeIf(vs, instr);
2719 DeoptimizeIf(ne, instr);
2740 void LCodeGen::DoDivByConstI(LDivByConstI* instr) {
2741 Register dividend = ToRegister32(instr->dividend());
2742 int32_t divisor = instr->divisor();
2743 Register result = ToRegister32(instr->result());
2747 Deoptimize(instr);
2752 HDiv* hdiv = instr->hydrogen();
2754 DeoptimizeIfZero(dividend, instr);
2761 Register temp = ToRegister32(instr->temp());
2766 DeoptimizeIfNotZero(temp, instr);
2772 void LCodeGen::DoDivI(LDivI* instr) {
2773 HBinaryOperation* hdiv = instr->hydrogen();
2774 Register dividend = ToRegister32(instr->dividend());
2775 Register divisor = ToRegister32(instr->divisor());
2776 Register result = ToRegister32(instr->result());
2783 DCHECK_EQ(NULL, instr->temp());
2789 DeoptimizeIfZero(divisor, instr);
2801 DeoptimizeIf(eq, instr);
2813 DeoptimizeIf(eq, instr);
2817 Register remainder = ToRegister32(instr->temp());
2819 DeoptimizeIfNotZero(remainder, instr);
2823 void LCodeGen::DoDoubleToIntOrSmi(LDoubleToIntOrSmi* instr) {
2824 DoubleRegister input = ToDoubleRegister(instr->value());
2825 Register result = ToRegister32(instr->result());
2827 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
2828 DeoptimizeIfMinusZero(input, instr);
2832 DeoptimizeIf(ne, instr);
2834 if (instr->tag_result()) {
2840 void LCodeGen::DoDrop(LDrop* instr) {
2841 __ Drop(instr->count());
2845 void LCodeGen::DoDummy(LDummy* instr) {
2850 void LCodeGen::DoDummyUse(LDummyUse* instr) {
2855 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
2856 DCHECK(ToRegister(instr->context()).is(cp));
2858 DCHECK(instr->IsMarkedAsCall());
2862 bool pretenure = instr->hydrogen()->pretenure();
2863 if (!pretenure && instr->hydrogen()->has_no_literals()) {
2864 FastNewClosureStub stub(isolate(), instr->hydrogen()->strict_mode(),
2865 instr->hydrogen()->kind());
2866 __ Mov(x2, Operand(instr->hydrogen()->shared_info()));
2867 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2869 __ Mov(x2, Operand(instr->hydrogen()->shared_info()));
2873 CallRuntime(Runtime::kNewClosure, 3, instr);
2878 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) {
2879 Register map = ToRegister(instr->map());
2880 Register result = ToRegister(instr->result());
2892 __ Ldr(result, FieldMemOperand(result, FixedArray::SizeFor(instr->idx())));
2893 DeoptimizeIfZero(result, instr);
2899 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
2900 Register object = ToRegister(instr->object());
2903 DCHECK(instr->IsMarkedAsCall());
2906 DeoptimizeIfRoot(object, Heap::kUndefinedValueRootIndex, instr);
2910 DeoptimizeIf(eq, instr);
2912 DeoptimizeIfSmi(object, instr);
2916 DeoptimizeIf(le, instr);
2927 CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr);
2930 DeoptimizeIfNotRoot(x1, Heap::kMetaMapRootIndex, instr);
2936 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
2937 Register input = ToRegister(instr->value());
2938 Register result = ToRegister(instr->result());
2957 void LCodeGen::DoGoto(LGoto* instr) {
2958 EmitGoto(instr->block_id());
2963 LHasCachedArrayIndexAndBranch* instr) {
2964 Register input = ToRegister(instr->value());
2965 Register temp = ToRegister32(instr->temp());
2971 EmitBranch(instr, eq);
2978 // - [ FIRST_TYPE, instr->to() ]
2979 // - [ instr->form(), LAST_TYPE ]
2980 // - instr->from() == instr->to()
2988 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
2989 InstanceType from = instr->from();
2990 InstanceType to = instr->to();
2998 static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
2999 InstanceType from = instr->from();
3000 InstanceType to = instr->to();
3009 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
3010 Register input = ToRegister(instr->value());
3011 Register scratch = ToRegister(instr->temp());
3013 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
3014 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
3016 __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen()));
3017 EmitBranch(instr, BranchCondition(instr->hydrogen()));
3021 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
3022 Register result = ToRegister(instr->result());
3023 Register base = ToRegister(instr->base_object());
3024 if (instr->offset()->IsConstantOperand()) {
3025 __ Add(result, base, ToOperand32(instr->offset()));
3027 __ Add(result, base, Operand(ToRegister32(instr->offset()), SXTW));
3032 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
3033 DCHECK(ToRegister(instr->context()).is(cp));
3035 DCHECK(ToRegister(instr->left()).Is(InstanceofStub::left()));
3036 DCHECK(ToRegister(instr->right()).Is(InstanceofStub::right()));
3039 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
3050 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
3054 LInstanceOfKnownGlobal* instr)
3055 : LDeferredCode(codegen), instr_(instr) { }
3059 virtual LInstruction* instr() { return instr_; }
3065 new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
3068 Register object = ToRegister(instr->value());
3069 Register result = ToRegister(instr->result());
3075 DCHECK(instr->IsMarkedAsCall());
3135 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
3136 Register result = ToRegister(instr->result());
3147 LoadContextFromDeferred(instr->context());
3150 DCHECK(ToRegister(instr->value()).Is(InstanceofStub::left()));
3151 __ LoadObject(InstanceofStub::right(), instr->function());
3156 instr,
3158 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment();
3166 void LCodeGen::DoInstructionGap(LInstructionGap* instr) {
3167 DoGap(instr);
3171 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
3172 Register value = ToRegister32(instr->value());
3173 DoubleRegister result = ToDoubleRegister(instr->result());
3178 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
3179 DCHECK(ToRegister(instr->context()).is(cp));
3181 DCHECK(ToRegister(instr->function()).is(x1));
3182 DCHECK(instr->HasPointerMap());
3184 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
3186 LPointerMap* pointers = instr->pointer_map();
3188 ParameterCount count(instr->arity());
3192 instr->hydrogen()->formal_parameter_count(),
3193 instr->arity(),
3194 instr,
3201 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
3202 Register temp1 = ToRegister(instr->temp1());
3203 Register temp2 = ToRegister(instr->temp2());
3220 instr, eq, temp1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
3224 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
3225 Label* is_object = instr->TrueLabel(chunk_);
3226 Label* is_not_object = instr->FalseLabel(chunk_);
3227 Register value = ToRegister(instr->value());
3228 Register map = ToRegister(instr->temp1());
3229 Register scratch = ToRegister(instr->temp2());
3245 EmitBranch(instr, le);
3262 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
3263 Register val = ToRegister(instr->value());
3264 Register scratch = ToRegister(instr->temp());
3267 instr->hydrogen()->value()->type().IsHeapObject()
3270 EmitIsString(val, scratch, instr->FalseLabel(chunk_), check_needed);
3272 EmitBranch(instr, true_cond);
3276 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
3277 Register value = ToRegister(instr->value());
3279 EmitTestAndBranch(instr, eq, value, kSmiTagMask);
3283 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
3284 Register input = ToRegister(instr->value());
3285 Register temp = ToRegister(instr->temp());
3287 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
3288 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
3293 EmitTestAndBranch(instr, ne, temp, 1 << Map::kIsUndetectable);
3317 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
3318 Register context = ToRegister(instr->context());
3319 Register result = ToRegister(instr->result());
3320 __ Ldr(result, ContextMemOperand(context, instr->slot_index()));
3321 if (instr->hydrogen()->RequiresHoleCheck()) {
3322 if (instr->hydrogen()->DeoptimizesOnHole()) {
3323 DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr);
3334 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
3335 Register function = ToRegister(instr->function());
3336 Register result = ToRegister(instr->result());
3337 Register temp = ToRegister(instr->temp());
3344 DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr);
3359 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
3360 Register result = ToRegister(instr->result());
3361 __ Mov(result, Operand(Handle<Object>(instr->hydrogen()->cell().handle())));
3363 if (instr->hydrogen()->RequiresHoleCheck()) {
3364 DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr);
3370 void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
3372 Register vector = ToRegister(instr->temp_vector());
3374 __ Mov(vector, instr->hydrogen()->feedback_vector());
3378 Smi::FromInt(instr->hydrogen()->slot()));
3382 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
3383 DCHECK(ToRegister(instr->context()).is(cp));
3384 DCHECK(ToRegister(instr->global_object())
3386 DCHECK(ToRegister(instr->result()).Is(x0));
3387 __ Mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
3389 EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
3391 ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
3393 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3428 void LCodeGen::DoLoadKeyedExternal(LLoadKeyedExternal* instr) {
3429 Register ext_ptr = ToRegister(instr->elements());
3431 ElementsKind elements_kind = instr->elements_kind();
3433 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi();
3434 bool key_is_constant = instr->key()->IsConstantOperand();
3438 DCHECK(instr->temp() == NULL);
3439 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
3444 scratch = ToRegister(instr->temp());
3445 key = ToRegister(instr->key());
3452 instr->base_offset());
3456 DoubleRegister result = ToDoubleRegister(instr->result());
3461 DoubleRegister result = ToDoubleRegister(instr->result());
3464 Register result = ToRegister(instr->result());
3492 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
3495 DeoptimizeIf(ne, instr);
3558 void LCodeGen::DoLoadKeyedFixedDouble(LLoadKeyedFixedDouble* instr) {
3559 Register elements = ToRegister(instr->elements());
3560 DoubleRegister result = ToDoubleRegister(instr->result());
3563 if (instr->key()->IsConstantOperand()) {
3564 DCHECK(instr->hydrogen()->RequiresHoleCheck() ||
3565 (instr->temp() == NULL));
3567 int constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
3571 int offset = instr->base_offset() + constant_key * kDoubleSize;
3574 Register load_base = ToRegister(instr->temp());
3575 Register key = ToRegister(instr->key());
3576 bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi();
3578 instr->hydrogen()->elements_kind(),
3579 instr->hydrogen()->representation(),
3580 instr->base_offset());
3585 if (instr->hydrogen()->RequiresHoleCheck()) {
3586 Register scratch = ToRegister(instr->temp());
3592 DeoptimizeIf(vs, instr);
3597 void LCodeGen::DoLoadKeyedFixed(LLoadKeyedFixed* instr) {
3598 Register elements = ToRegister(instr->elements());
3599 Register result = ToRegister(instr->result());
3602 Representation representation = instr->hydrogen()->representation();
3603 if (instr->key()->IsConstantOperand()) {
3604 DCHECK(instr->temp() == NULL);
3605 LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
3606 int offset = instr->base_offset() +
3609 DCHECK(instr->hydrogen()->elements_kind() == FAST_SMI_ELEMENTS);
3617 Register load_base = ToRegister(instr->temp());
3618 Register key = ToRegister(instr->key());
3619 bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi();
3622 instr->hydrogen()->elements_kind(),
3623 representation, instr->base_offset());
3628 if (instr->hydrogen()->RequiresHoleCheck()) {
3629 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
3630 DeoptimizeIfNotSmi(result, instr);
3632 DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr);
3638 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
3639 DCHECK(ToRegister(instr->context()).is(cp));
3640 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister()));
3641 DCHECK(ToRegister(instr->key()).is(LoadDescriptor::NameRegister()));
3643 EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
3647 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3649 DCHECK(ToRegister(instr->result()).Is(x0));
3653 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
3654 HObjectAccess access = instr->hydrogen()->access();
3656 Register object = ToRegister(instr->object());
3659 Register result = ToRegister(instr->result());
3664 if (instr->hydrogen()->representation().IsDouble()) {
3665 FPRegister result = ToDoubleRegister(instr->result());
3670 Register result = ToRegister(instr->result());
3681 instr->hydrogen()->representation().IsInteger32()) {
3693 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
3694 DCHECK(ToRegister(instr->context()).is(cp));
3696 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister()));
3697 __ Mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
3699 EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
3703 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3705 DCHECK(ToRegister(instr->result()).is(x0));
3709 void LCodeGen::DoLoadRoot(LLoadRoot* instr) {
3710 Register result = ToRegister(instr->result());
3711 __ LoadRoot(result, instr->index());
3715 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
3716 Register result = ToRegister(instr->result());
3717 Register map = ToRegister(instr->value());
3722 void LCodeGen::DoMathAbs(LMathAbs* instr) {
3723 Representation r = instr->hydrogen()->value()->representation();
3725 DoubleRegister input = ToDoubleRegister(instr->value());
3726 DoubleRegister result = ToDoubleRegister(instr->result());
3729 Register input = r.IsSmi() ? ToRegister(instr->value())
3730 : ToRegister32(instr->value());
3731 Register result = r.IsSmi() ? ToRegister(instr->result())
3732 : ToRegister32(instr->result());
3734 DeoptimizeIf(vs, instr);
3739 void LCodeGen::DoDeferredMathAbsTagged(LMathAbsTagged* instr,
3751 DCHECK(instr->context() != NULL);
3752 DCHECK(ToRegister(instr->context()).is(cp));
3753 Register input = ToRegister(instr->value());
3754 Register temp1 = ToRegister(instr->temp1());
3755 Register temp2 = ToRegister(instr->temp2());
3756 Register result_bits = ToRegister(instr->temp3());
3757 Register result = ToRegister(instr->result());
3762 DeoptimizeIfNotHeapNumber(input, instr);
3789 Register input = ToRegister(instr->value());
3797 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr,
3798 instr->context());
3805 void LCodeGen::DoMathAbsTagged(LMathAbsTagged* instr) {
3809 DeferredMathAbsTagged(LCodeGen* codegen, LMathAbsTagged* instr)
3810 : LDeferredCode(codegen), instr_(instr) { }
3815 virtual LInstruction* instr() { return instr_; }
3827 new(zone()) DeferredMathAbsTagged(this, instr);
3829 DCHECK(instr->hydrogen()->value()->representation().IsTagged() ||
3830 instr->hydrogen()->value()->representation().IsSmi());
3831 Register input = ToRegister(instr->value());
3832 Register result_bits = ToRegister(instr->temp3());
3833 Register result = ToRegister(instr->result());
3858 void LCodeGen::DoMathExp(LMathExp* instr) {
3859 DoubleRegister input = ToDoubleRegister(instr->value());
3860 DoubleRegister result = ToDoubleRegister(instr->result());
3861 DoubleRegister double_temp1 = ToDoubleRegister(instr->double_temp1());
3863 Register temp1 = ToRegister(instr->temp1());
3864 Register temp2 = ToRegister(instr->temp2());
3865 Register temp3 = ToRegister(instr->temp3());
3873 void LCodeGen::DoMathFloorD(LMathFloorD* instr) {
3874 DoubleRegister input = ToDoubleRegister(instr->value());
3875 DoubleRegister result = ToDoubleRegister(instr->result());
3881 void LCodeGen::DoMathFloorI(LMathFloorI* instr) {
3882 DoubleRegister input = ToDoubleRegister(instr->value());
3883 Register result = ToRegister(instr->result());
3885 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3886 DeoptimizeIfMinusZero(input, instr);
3896 DeoptimizeIf(ne, instr);
3900 void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
3901 Register dividend = ToRegister32(instr->dividend());
3902 Register result = ToRegister32(instr->result());
3903 int32_t divisor = instr->divisor();
3921 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3922 DeoptimizeIf(eq, instr);
3927 if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
3928 DeoptimizeIf(vs, instr);
3934 if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
3944 void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
3945 Register dividend = ToRegister32(instr->dividend());
3946 int32_t divisor = instr->divisor();
3947 Register result = ToRegister32(instr->result());
3951 Deoptimize(instr);
3956 HMathFloorOfDiv* hdiv = instr->hydrogen();
3958 DeoptimizeIfZero(dividend, instr);
3972 Register temp = ToRegister32(instr->temp());
3990 void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) {
3991 Register dividend = ToRegister32(instr->dividend());
3992 Register divisor = ToRegister32(instr->divisor());
3993 Register remainder = ToRegister32(instr->temp());
3994 Register result = ToRegister32(instr->result());
4001 DeoptimizeIfZero(divisor, instr);
4004 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
4008 DeoptimizeIf(eq, instr);
4012 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
4018 DeoptimizeIf(eq, instr);
4035 void LCodeGen::DoMathLog(LMathLog* instr) {
4036 DCHECK(instr->IsMarkedAsCall());
4037 DCHECK(ToDoubleRegister(instr->value()).is(d0));
4040 DCHECK(ToDoubleRegister(instr->result()).Is(d0));
4044 void LCodeGen::DoMathClz32(LMathClz32* instr) {
4045 Register input = ToRegister32(instr->value());
4046 Register result = ToRegister32(instr->result());
4051 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
4052 DoubleRegister input = ToDoubleRegister(instr->value());
4053 DoubleRegister result = ToDoubleRegister(instr->result());
4075 void LCodeGen::DoPower(LPower* instr) {
4076 Representation exponent_type = instr->hydrogen()->right()->representation();
4081 DCHECK(!instr->right()->IsDoubleRegister() ||
4082 ToDoubleRegister(instr->right()).is(d1));
4083 DCHECK(exponent_type.IsInteger32() || !instr->right()->IsRegister() ||
4084 ToRegister(instr->right()).is(tagged_exponent));
4086 ToRegister(instr->right()).is(integer_exponent));
4087 DCHECK(ToDoubleRegister(instr->left()).is(d0));
4088 DCHECK(ToDoubleRegister(instr->result()).is(d0));
4096 DeoptimizeIfNotHeapNumber(tagged_exponent, instr);
4114 void LCodeGen::DoMathRoundD(LMathRoundD* instr) {
4115 DoubleRegister input = ToDoubleRegister(instr->value());
4116 DoubleRegister result = ToDoubleRegister(instr->result());
4144 void LCodeGen::DoMathRoundI(LMathRoundI* instr) {
4145 DoubleRegister input = ToDoubleRegister(instr->value());
4146 DoubleRegister temp = ToDoubleRegister(instr->temp1());
4148 Register result = ToRegister(instr->result());
4177 DeoptimizeIf(hi, instr);
4181 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
4183 DeoptimizeIfNegative(result, instr);
4188 DeoptimizeIf(vs, instr);
4198 void LCodeGen::DoMathFround(LMathFround* instr) {
4199 DoubleRegister input = ToDoubleRegister(instr->value());
4200 DoubleRegister result = ToDoubleRegister(instr->result());
4206 void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
4207 DoubleRegister input = ToDoubleRegister(instr->value());
4208 DoubleRegister result = ToDoubleRegister(instr->result());
4213 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
4214 HMathMinMax::Operation op = instr->hydrogen()->operation();
4215 if (instr->hydrogen()->representation().IsInteger32()) {
4216 Register result = ToRegister32(instr->result());
4217 Register left = ToRegister32(instr->left());
4218 Operand right = ToOperand32(instr->right());
4222 } else if (instr->hydrogen()->representation().IsSmi()) {
4223 Register result = ToRegister(instr->result());
4224 Register left = ToRegister(instr->left());
4225 Operand right = ToOperand(instr->right());
4230 DCHECK(instr->hydrogen()->representation().IsDouble());
4231 DoubleRegister result = ToDoubleRegister(instr->result());
4232 DoubleRegister left = ToDoubleRegister(instr->left());
4233 DoubleRegister right = ToDoubleRegister(instr->right());
4245 void LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) {
4246 Register dividend = ToRegister32(instr->dividend());
4247 int32_t divisor = instr->divisor();
4248 DCHECK(dividend.is(ToRegister32(instr->result())));
4256 HMod* hmod = instr->hydrogen();
4266 DeoptimizeIf(eq, instr);
4277 void LCodeGen::DoModByConstI(LModByConstI* instr) {
4278 Register dividend = ToRegister32(instr->dividend());
4279 int32_t divisor = instr->divisor();
4280 Register result = ToRegister32(instr->result());
4281 Register temp = ToRegister32(instr->temp());
4285 Deoptimize(instr);
4295 HMod* hmod = instr->hydrogen();
4299 DeoptimizeIfNegative(dividend, instr);
4305 void LCodeGen::DoModI(LModI* instr) {
4306 Register dividend = ToRegister32(instr->left());
4307 Register divisor = ToRegister32(instr->right());
4308 Register result = ToRegister32(instr->result());
4313 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
4314 DeoptimizeIfZero(divisor, instr);
4317 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
4319 DeoptimizeIfNegative(dividend, instr);
4325 void LCodeGen::DoMulConstIS(LMulConstIS* instr) {
4326 DCHECK(instr->hydrogen()->representation().IsSmiOrInteger32());
4327 bool is_smi = instr->hydrogen()->representation().IsSmi();
4329 is_smi ? ToRegister(instr->result()) : ToRegister32(instr->result());
4331 is_smi ? ToRegister(instr->left()) : ToRegister32(instr->left()) ;
4332 int32_t right = ToInteger32(instr->right());
4335 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
4337 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
4342 DeoptimizeIfZero(left, instr);
4345 DeoptimizeIfNegative(left, instr);
4355 DeoptimizeIf(vs, instr);
4371 DeoptimizeIf(vs, instr);
4390 DeoptimizeIf(lt, instr);
4400 DeoptimizeIf(vs, instr);
4441 void LCodeGen::DoMulI(LMulI* instr) {
4442 Register result = ToRegister32(instr->result());
4443 Register left = ToRegister32(instr->left());
4444 Register right = ToRegister32(instr->right());
4446 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
4448 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
4458 DeoptimizeIf(mi, instr);
4464 DeoptimizeIf(ne, instr);
4471 void LCodeGen::DoMulS(LMulS* instr) {
4472 Register result = ToRegister(instr->result());
4473 Register left = ToRegister(instr->left());
4474 Register right = ToRegister(instr->right());
4476 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
4478 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
4488 DeoptimizeIf(mi, instr);
4496 DeoptimizeIf(ne, instr);
4521 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
4525 Register result = ToRegister(instr->result());
4537 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4542 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
4545 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4546 : LDeferredCode(codegen), instr_(instr) { }
4548 virtual LInstruction* instr() { return instr_; }
4553 DoubleRegister input = ToDoubleRegister(instr->value());
4554 Register result = ToRegister(instr->result());
4555 Register temp1 = ToRegister(instr->temp1());
4556 Register temp2 = ToRegister(instr->temp2());
4558 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4570 void LCodeGen::DoDeferredNumberTagU(LInstruction* instr,
4576 Register dst = ToRegister(instr->result());
4603 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4616 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4619 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
4620 : LDeferredCode(codegen), instr_(instr) { }
4627 virtual LInstruction* instr() { return instr_; }
4632 Register value = ToRegister32(instr->value());
4633 Register result = ToRegister(instr->result());
4635 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4643 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
4644 Register input = ToRegister(instr->value());
4645 Register scratch = ToRegister(instr->temp());
4646 DoubleRegister result = ToDoubleRegister(instr->result());
4648 instr->hydrogen()->can_convert_undefined_to_nan();
4653 HValue* value = instr->hydrogen()->value();
4666 DeoptimizeIfNotHeapNumber(input, instr);
4671 if (instr->hydrogen()->deoptimize_on_minus_zero()) {
4672 DeoptimizeIfMinusZero(result, instr);
4678 DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex, instr);
4698 void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
4702 LEnvironment* environment = instr->environment();
4713 void LCodeGen::DoParameter(LParameter* instr) {
4718 void LCodeGen::DoPreparePushArguments(LPreparePushArguments* instr) {
4719 __ PushPreamble(instr->argc(), kPointerSize);
4723 void LCodeGen::DoPushArguments(LPushArguments* instr) {
4726 for (int i = 0; i < instr->ArgumentCount(); ++i) {
4727 LOperand* arg = instr->argument(i);
4742 void LCodeGen::DoReturn(LReturn* instr) {
4765 if (instr->has_constant_parameter_count()) {
4766 int parameter_count = ToInteger32(instr->constant_parameter_count());
4769 Register parameter_count = ToRegister(instr->parameter_count());
4803 void LCodeGen::DoSeqStringGetChar(LSeqStringGetChar* instr) {
4804 String::Encoding encoding = instr->hydrogen()->encoding();
4805 Register string = ToRegister(instr->string());
4806 Register result = ToRegister(instr->result());
4807 Register temp = ToRegister(instr->temp());
4829 BuildSeqStringOperand(string, temp, instr->index(), encoding);
4838 void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
4839 String::Encoding encoding = instr->hydrogen()->encoding();
4840 Register string = ToRegister(instr->string());
4841 Register value = ToRegister(instr->value());
4842 Register temp = ToRegister(instr->temp());
4845 DCHECK(ToRegister(instr->context()).is(cp));
4846 Register index = ToRegister(instr->index());
4850 instr->hydrogen()->encoding() == String::ONE_BYTE_ENCODING
4856 BuildSeqStringOperand(string, temp, instr->index(), encoding);
4865 void LCodeGen::DoSmiTag(LSmiTag* instr) {
4866 HChange* hchange = instr->hydrogen();
4867 Register input = ToRegister(instr->value());
4868 Register output = ToRegister(instr->result());
4871 DeoptimizeIfNegative(input.W(), instr);
4877 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
4878 Register input = ToRegister(instr->value());
4879 Register result = ToRegister(instr->result());
4882 if (instr->needs_check()) {
4883 DeoptimizeIfNotSmi(input, instr);
4892 void LCodeGen::DoShiftI(LShiftI* instr) {
4893 LOperand* right_op = instr->right();
4894 Register left = ToRegister32(instr->left());
4895 Register result = ToRegister32(instr->result());
4898 Register right = ToRegister32(instr->right());
4899 switch (instr->op()) {
4905 if (instr->can_deopt()) {
4908 DeoptimizeIfNegative(result, instr);
4917 if ((instr->op() == Token::SHR) && instr->can_deopt()) {
4918 DeoptimizeIfNegative(left, instr);
4922 switch (instr->op()) {
4934 void LCodeGen::DoShiftS(LShiftS* instr) {
4935 LOperand* right_op = instr->right();
4936 Register left = ToRegister(instr->left());
4937 Register result = ToRegister(instr->result());
4940 Register right = ToRegister(instr->right());
4947 switch (instr->op()) {
4968 if (instr->can_deopt()) {
4971 DeoptimizeIfNegative(result, instr);
4980 if ((instr->op() == Token::SHR) && instr->can_deopt()) {
4981 DeoptimizeIfNegative(left, instr);
4985 switch (instr->op()) {
5009 void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
5014 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
5015 DCHECK(ToRegister(instr->context()).is(cp));
5018 DCHECK(instr->IsMarkedAsCall());
5023 __ LoadHeapObject(scratch1, instr->hydrogen()->pairs());
5024 __ Mov(scratch2, Smi::FromInt(instr->hydrogen()->flags()));
5026 CallRuntime(Runtime::kDeclareGlobals, 3, instr);
5030 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
5032 LoadContextFromDeferred(instr->context());
5035 instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
5036 DCHECK(instr->HasEnvironment());
5037 LEnvironment* env = instr->environment();
5042 void LCodeGen::DoStackCheck(LStackCheck* instr) {
5045 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
5046 : LDeferredCode(codegen), instr_(instr) { }
5048 virtual LInstruction* instr() { return instr_; }
5053 DCHECK(instr->HasEnvironment());
5054 LEnvironment* env = instr->environment();
5057 if (instr->hydrogen()->is_function_entry()) {
5065 DCHECK(instr->context()->IsRegister());
5066 DCHECK(ToRegister(instr->context()).is(cp));
5069 instr);
5072 DCHECK(instr->hydrogen()->is_backwards_branch());
5075 new(zone()) DeferredStackCheck(this, instr);
5080 __ Bind(instr->done_label());
5081 deferred_stack_check->SetExit(instr->done_label());
5090 void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) {
5091 Register function = ToRegister(instr->function());
5092 Register code_object = ToRegister(instr->code_object());
5093 Register temp = ToRegister(instr->temp());
5099 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
5100 Register context = ToRegister(instr->context());
5101 Register value = ToRegister(instr->value());
5102 Register scratch = ToRegister(instr->temp());
5103 MemOperand target = ContextMemOperand(context, instr->slot_index());
5107 if (instr->hydrogen()->RequiresHoleCheck()) {
5109 if (instr->hydrogen()->DeoptimizesOnHole()) {
5110 DeoptimizeIfRoot(scratch, Heap::kTheHoleValueRootIndex, instr);
5117 if (instr->hydrogen()->NeedsWriteBarrier()) {
5119 instr->hydrogen()->value()->type().IsHeapObject()
5134 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
5135 Register value = ToRegister(instr->value());
5136 Register cell = ToRegister(instr->temp1());
5139 __ Mov(cell, Operand(instr->hydrogen()->cell().handle()));
5145 if (instr->hydrogen()->RequiresHoleCheck()) {
5146 Register payload = ToRegister(instr->temp2());
5148 DeoptimizeIfRoot(payload, Heap::kTheHoleValueRootIndex, instr);
5157 void LCodeGen::DoStoreKeyedExternal(LStoreKeyedExternal* instr) {
5158 Register ext_ptr = ToRegister(instr->elements());
5161 ElementsKind elements_kind = instr->elements_kind();
5163 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi();
5164 bool key_is_constant = instr->key()->IsConstantOperand();
5167 DCHECK(instr->temp() == NULL);
5168 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
5173 key = ToRegister(instr->key());
5174 scratch = ToRegister(instr->temp());
5181 instr->base_offset());
5185 DoubleRegister value = ToDoubleRegister(instr->value());
5191 DoubleRegister value = ToDoubleRegister(instr->value());
5194 Register value = ToRegister(instr->value());
5236 void LCodeGen::DoStoreKeyedFixedDouble(LStoreKeyedFixedDouble* instr) {
5237 Register elements = ToRegister(instr->elements());
5238 DoubleRegister value = ToDoubleRegister(instr->value());
5241 if (instr->key()->IsConstantOperand()) {
5242 int constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
5246 int offset = instr->base_offset() + constant_key * kDoubleSize;
5249 Register store_base = ToRegister(instr->temp());
5250 Register key = ToRegister(instr->key());
5251 bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi();
5253 instr->hydrogen()->elements_kind(),
5254 instr->hydrogen()->representation(),
5255 instr->base_offset());
5258 if (instr->NeedsCanonicalization()) {
5267 void LCodeGen::DoStoreKeyedFixed(LStoreKeyedFixed* instr) {
5268 Register value = ToRegister(instr->value());
5269 Register elements = ToRegister(instr->elements());
5275 if (!instr->key()->IsConstantOperand() ||
5276 instr->hydrogen()->NeedsWriteBarrier()) {
5277 scratch = ToRegister(instr->temp());
5280 Representation representation = instr->hydrogen()->value()->representation();
5281 if (instr->key()->IsConstantOperand()) {
5282 LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
5283 int offset = instr->base_offset() +
5287 DCHECK(instr->hydrogen()->store_mode() == STORE_TO_INITIALIZED_ENTRY);
5288 DCHECK(instr->hydrogen()->elements_kind() == FAST_SMI_ELEMENTS);
5297 key = ToRegister(instr->key());
5298 bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi();
5301 instr->hydrogen()->elements_kind(),
5302 representation, instr->base_offset());
5307 if (instr->hydrogen()->NeedsWriteBarrier()) {
5312 instr->hydrogen()->value()->type().IsHeapObject()
5318 instr->hydrogen()->PointersToHereCheckForValue());
5323 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
5324 DCHECK(ToRegister(instr->context()).is(cp));
5325 DCHECK(ToRegister(instr->object()).is(StoreDescriptor::ReceiverRegister()));
5326 DCHECK(ToRegister(instr->key()).is(StoreDescriptor::NameRegister()));
5327 DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister()));
5330 CodeFactory::KeyedStoreIC(isolate(), instr->strict_mode()).code();
5331 CallCode(ic, RelocInfo::CODE_TARGET, instr);
5335 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
5336 Representation representation = instr->representation();
5338 Register object = ToRegister(instr->object());
5339 HObjectAccess access = instr->hydrogen()->access();
5343 DCHECK(!instr->hydrogen()->has_transition());
5344 DCHECK(!instr->hydrogen()->NeedsWriteBarrier());
5345 Register value = ToRegister(instr->value());
5354 DCHECK(!instr->hydrogen()->has_transition());
5355 DCHECK(!instr->hydrogen()->NeedsWriteBarrier());
5356 FPRegister value = ToDoubleRegister(instr->value());
5361 Register value = ToRegister(instr->value());
5364 !instr->value()->IsConstantOperand() ||
5365 IsInteger32Constant(LConstantOperand::cast(instr->value())));
5367 if (instr->hydrogen()->has_transition()) {
5368 Handle<Map> transition = instr->hydrogen()->transition_map();
5371 Register new_map_value = ToRegister(instr->temp0());
5374 if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
5378 ToRegister(instr->temp1()),
5389 Register temp0 = ToRegister(instr->temp0());
5395 instr->hydrogen()->value()->representation().IsInteger32()) {
5396 DCHECK(instr->hydrogen()->store_mode() == STORE_TO_INITIALIZED_ENTRY);
5398 Register temp0 = ToRegister(instr->temp0());
5415 if (instr->hydrogen()->NeedsWriteBarrier()) {
5419 ToRegister(instr->temp1()), // Clobbered.
5423 instr->hydrogen()->SmiCheckForWriteBarrier(),
5424 instr->hydrogen()->PointersToHereCheckForValue());
5429 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
5430 DCHECK(ToRegister(instr->context()).is(cp));
5431 DCHECK(ToRegister(instr->object()).is(StoreDescriptor::ReceiverRegister()));
5432 DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister()));
5434 __ Mov(StoreDescriptor::NameRegister(), Operand(instr->name()));
5435 Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode());
5436 CallCode(ic, RelocInfo::CODE_TARGET, instr);
5440 void LCodeGen::DoStringAdd(LStringAdd* instr) {
5441 DCHECK(ToRegister(instr->context()).is(cp));
5442 DCHECK(ToRegister(instr->left()).Is(x1));
5443 DCHECK(ToRegister(instr->right()).Is(x0));
5445 instr->hydrogen()->flags(),
5446 instr->hydrogen()->pretenure_flag());
5447 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
5451 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
5454 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
5455 : LDeferredCode(codegen), instr_(instr) { }
5457 virtual LInstruction* instr() { return instr_; }
5463 new(zone()) DeferredStringCharCodeAt(this, instr);
5466 ToRegister(instr->string()),
5467 ToRegister32(instr->index()),
5468 ToRegister(instr->result()),
5474 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
5475 Register string = ToRegister(instr->string());
5476 Register result = ToRegister(instr->result());
5487 Register index = ToRegister(instr->index());
5490 CallRuntimeFromDeferred(Runtime::kStringCharCodeAtRT, 2, instr,
5491 instr->context());
5498 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
5501 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
5502 : LDeferredCode(codegen), instr_(instr) { }
5504 virtual LInstruction* instr() { return instr_; }
5510 new(zone()) DeferredStringCharFromCode(this, instr);
5512 DCHECK(instr->hydrogen()->value()->representation().IsInteger32());
5513 Register char_code = ToRegister32(instr->char_code());
5514 Register result = ToRegister(instr->result());
5527 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
5528 Register char_code = ToRegister(instr->char_code());
5529 Register result = ToRegister(instr->result());
5538 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context());
5543 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
5544 DCHECK(ToRegister(instr->context()).is(cp));
5545 Token::Value op = instr->op();
5548 CallCode(ic, RelocInfo::CODE_TARGET, instr);
5553 EmitCompareAndBranch(instr, condition, x0, 0);
5557 void LCodeGen::DoSubI(LSubI* instr) {
5558 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
5559 Register result = ToRegister32(instr->result());
5560 Register left = ToRegister32(instr->left());
5561 Operand right = ToShiftedRightOperand32(instr->right(), instr);
5565 DeoptimizeIf(vs, instr);
5572 void LCodeGen::DoSubS(LSubS* instr) {
5573 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
5574 Register result = ToRegister(instr->result());
5575 Register left = ToRegister(instr->left());
5576 Operand right = ToOperand(instr->right());
5579 DeoptimizeIf(vs, instr);
5586 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr,
5596 if (instr->truncating()) {
5597 Register output = ToRegister(instr->result());
5619 DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex, instr);
5621 Register output = ToRegister32(instr->result());
5624 DeoptimizeIfNotHeapNumber(input, instr);
5630 DeoptimizeIf(ne, instr, "lost precision or NaN");
5632 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5636 DeoptimizeIfNegative(scratch1, instr, "minus zero");
5643 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
5646 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
5647 : LDeferredCode(codegen), instr_(instr) { }
5653 virtual LInstruction* instr() { return instr_; }
5658 Register input = ToRegister(instr->value());
5659 Register output = ToRegister(instr->result());
5661 if (instr->hydrogen()->value()->representation().IsSmi()) {
5664 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
5673 void LCodeGen::DoThisFunction(LThisFunction* instr) {
5674 Register result = ToRegister(instr->result());
5679 void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
5680 DCHECK(ToRegister(instr->value()).Is(x0));
5681 DCHECK(ToRegister(instr->result()).Is(x0));
5683 CallRuntime(Runtime::kToFastProperties, 1, instr);
5687 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
5688 DCHECK(ToRegister(instr->context()).is(cp));
5696 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
5697 __ LoadObject(x7, instr->hydrogen()->literals());
5703 __ Mov(x12, Operand(Smi::FromInt(instr->hydrogen()->literal_index())));
5704 __ Mov(x11, Operand(instr->hydrogen()->pattern()));
5705 __ Mov(x10, Operand(instr->hydrogen()->flags()));
5707 CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr);
5720 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr);
5729 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
5730 Register object = ToRegister(instr->object());
5732 Handle<Map> from_map = instr->original_map();
5733 Handle<Map> to_map = instr->transitioned_map();
5734 ElementsKind from_kind = instr->from_kind();
5735 ElementsKind to_kind = instr->to_kind();
5740 Register temp1 = ToRegister(instr->temp1());
5741 Register new_map = ToRegister(instr->temp2());
5757 DCHECK(ToRegister(instr->context()).is(cp));
5764 instr->pointer_map(), 0, Safepoint::kLazyDeopt);
5770 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
5771 Register object = ToRegister(instr->object());
5772 Register temp1 = ToRegister(instr->temp1());
5773 Register temp2 = ToRegister(instr->temp2());
5777 DeoptimizeIf(eq, instr);
5782 void LCodeGen::DoTruncateDoubleToIntOrSmi(LTruncateDoubleToIntOrSmi* instr) {
5783 DoubleRegister input = ToDoubleRegister(instr->value());
5784 Register result = ToRegister(instr->result());
5786 if (instr->tag_result()) {
5792 void LCodeGen::DoTypeof(LTypeof* instr) {
5793 Register input = ToRegister(instr->value());
5795 CallRuntime(Runtime::kTypeof, 1, instr);
5799 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
5800 Handle<String> type_name = instr->type_literal();
5801 Label* true_label = instr->TrueLabel(chunk_);
5802 Label* false_label = instr->FalseLabel(chunk_);
5803 Register value = ToRegister(instr->value());
5809 int true_block = instr->TrueDestination(chunk_);
5810 int false_block = instr->FalseDestination(chunk_);
5825 DCHECK((instr->temp1() != NULL) && (instr->temp2() != NULL));
5826 Register map = ToRegister(instr->temp1());
5827 Register scratch = ToRegister(instr->temp2());
5833 EmitTestAndBranch(instr, eq, scratch, 1 << Map::kIsUndetectable);
5836 DCHECK((instr->temp1() != NULL) && (instr->temp2() != NULL));
5837 Register map = ToRegister(instr->temp1());
5838 Register scratch = ToRegister(instr->temp2());
5842 EmitBranch(instr, eq);
5847 EmitBranch(instr, eq);
5850 DCHECK(instr->temp1() != NULL);
5851 Register scratch = ToRegister(instr->temp1());
5858 EmitTestAndBranch(instr, ne, scratch, 1 << Map::kIsUndetectable);
5862 DCHECK(instr->temp1() != NULL);
5863 Register type = ToRegister(instr->temp1());
5868 EmitCompareAndBranch(instr, eq, type, JS_FUNCTION_PROXY_TYPE);
5871 DCHECK((instr->temp1() != NULL) && (instr->temp2() != NULL));
5872 Register map = ToRegister(instr->temp1());
5873 Register scratch = ToRegister(instr->temp2());
5883 EmitTestAndBranch(instr, eq, scratch, 1 << Map::kIsUndetectable);
5891 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
5892 __ Ucvtf(ToDoubleRegister(instr->result()), ToRegister32(instr->value()));
5896 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
5897 Register object = ToRegister(instr->value());
5898 Register map = ToRegister(instr->map());
5899 Register temp = ToRegister(instr->temp());
5902 DeoptimizeIf(ne, instr);
5906 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
5907 Register receiver = ToRegister(instr->receiver());
5908 Register function = ToRegister(instr->function());
5909 Register result = ToRegister(instr->result());
5916 if (!instr->hydrogen()->known_function()) {
5936 DeoptimizeIfSmi(receiver, instr);
5939 Deoptimize(instr);
5953 void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
5963 instr->pointer_map(), 2, Safepoint::kNoLazyDeopt);
5968 void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
5972 LLoadFieldByIndex* instr,
5977 instr_(instr),
5985 virtual LInstruction* instr() OVERRIDE { return instr_; }
5992 Register object = ToRegister(instr->object());
5993 Register index = ToRegister(instr->index());
5994 Register result = ToRegister(instr->result());
6000 this, instr, result, object, index);
6028 void LCodeGen::DoStoreFrameContext(LStoreFrameContext* instr) {
6029 Register context = ToRegister(instr->context());
6034 void LCodeGen::DoAllocateBlockContext(LAllocateBlockContext* instr) {
6035 Handle<ScopeInfo> scope_info = instr->scope_info();
6037 __ Push(ToRegister(instr->function()));
6038 CallRuntime(Runtime::kPushBlockContext, 2, instr);