Lines Matching refs:instr

270 void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
271 if (instr->IsCall()) {
274 if (!instr->IsLazyBailout() && !instr->IsGap()) {
294 code->instr()->hydrogen_value()->id(),
295 code->instr()->Mnemonic());
727 LInstruction* instr) {
728 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT);
734 LInstruction* instr,
736 DCHECK(instr != NULL);
738 RecordSafepointWithLazyDeopt(instr, safepoint_mode);
744 LInstruction* instr,
746 DCHECK(instr != NULL);
750 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
771 LInstruction* instr,
776 instr->pointer_map(), argc, Safepoint::kNoLazyDeopt);
817 void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr,
821 LEnvironment* environment = instr->environment();
861 Deoptimizer::Reason reason(instr->hydrogen_value()->position().raw(),
862 instr->Mnemonic(), detail);
884 void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr,
890 DeoptimizeIf(condition, instr, bailout_type, src1, src2, detail);
965 LInstruction* instr, SafepointMode safepoint_mode) {
967 RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt);
971 instr->pointer_map(), 0, Safepoint::kLazyDeopt);
1059 void LCodeGen::DoInstructionGap(LInstructionGap* instr) {
1060 DoGap(instr);
1064 void LCodeGen::DoParameter(LParameter* instr) {
1069 void LCodeGen::DoCallStub(LCallStub* instr) {
1070 DCHECK(ToRegister(instr->context()).is(cp));
1071 DCHECK(ToRegister(instr->result()).is(v0));
1072 switch (instr->hydrogen()->major_key()) {
1075 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1080 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1085 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1094 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
1099 void LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) {
1100 Register dividend = ToRegister(instr->dividend());
1101 int32_t divisor = instr->divisor();
1102 DCHECK(dividend.is(ToRegister(instr->result())));
1110 HMod* hmod = instr->hydrogen();
1120 DeoptimizeIf(eq, instr, dividend, Operand(zero_reg));
1132 void LCodeGen::DoModByConstI(LModByConstI* instr) {
1133 Register dividend = ToRegister(instr->dividend());
1134 int32_t divisor = instr->divisor();
1135 Register result = ToRegister(instr->result());
1139 DeoptimizeIf(al, instr);
1148 HMod* hmod = instr->hydrogen();
1152 DeoptimizeIf(lt, instr, dividend, Operand(zero_reg));
1158 void LCodeGen::DoModI(LModI* instr) {
1159 HMod* hmod = instr->hydrogen();
1160 const Register left_reg = ToRegister(instr->left());
1161 const Register right_reg = ToRegister(instr->right());
1162 const Register result_reg = ToRegister(instr->result());
1171 DeoptimizeIf(eq, instr, right_reg, Operand(zero_reg));
1180 DeoptimizeIf(eq, instr, right_reg, Operand(-1));
1192 DeoptimizeIf(eq, instr, result_reg, Operand(zero_reg));
1198 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
1199 Register dividend = ToRegister(instr->dividend());
1200 int32_t divisor = instr->divisor();
1201 Register result = ToRegister(instr->result());
1206 HDiv* hdiv = instr->hydrogen();
1208 DeoptimizeIf(eq, instr, dividend, Operand(zero_reg));
1212 DeoptimizeIf(eq, instr, dividend, Operand(kMinInt));
1219 DeoptimizeIf(ne, instr, at, Operand(zero_reg));
1242 void LCodeGen::DoDivByConstI(LDivByConstI* instr) {
1243 Register dividend = ToRegister(instr->dividend());
1244 int32_t divisor = instr->divisor();
1245 Register result = ToRegister(instr->result());
1249 DeoptimizeIf(al, instr);
1254 HDiv* hdiv = instr->hydrogen();
1256 DeoptimizeIf(eq, instr, dividend, Operand(zero_reg));
1265 DeoptimizeIf(ne, instr, scratch0(), Operand(zero_reg));
1271 void LCodeGen::DoDivI(LDivI* instr) {
1272 HBinaryOperation* hdiv = instr->hydrogen();
1273 Register dividend = ToRegister(instr->dividend());
1274 Register divisor = ToRegister(instr->divisor());
1275 const Register result = ToRegister(instr->result());
1276 Register remainder = ToRegister(instr->temp());
1284 DeoptimizeIf(eq, instr, divisor, Operand(zero_reg));
1291 DeoptimizeIf(lt, instr, divisor, Operand(zero_reg));
1300 DeoptimizeIf(eq, instr, divisor, Operand(-1));
1305 DeoptimizeIf(ne, instr, remainder, Operand(zero_reg));
1310 void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) {
1311 DoubleRegister addend = ToDoubleRegister(instr->addend());
1312 DoubleRegister multiplier = ToDoubleRegister(instr->multiplier());
1313 DoubleRegister multiplicand = ToDoubleRegister(instr->multiplicand());
1316 DCHECK(addend.is(ToDoubleRegister(instr->result())));
1322 void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
1323 Register dividend = ToRegister(instr->dividend());
1324 Register result = ToRegister(instr->result());
1325 int32_t divisor = instr->divisor();
1350 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1351 DeoptimizeIf(eq, instr, result, Operand(zero_reg));
1357 if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
1358 DeoptimizeIf(ge, instr, scratch, Operand(zero_reg));
1364 if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
1379 void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
1380 Register dividend = ToRegister(instr->dividend());
1381 int32_t divisor = instr->divisor();
1382 Register result = ToRegister(instr->result());
1386 DeoptimizeIf(al, instr);
1391 HMathFloorOfDiv* hdiv = instr->hydrogen();
1393 DeoptimizeIf(eq, instr, dividend, Operand(zero_reg));
1407 Register temp = ToRegister(instr->temp());
1425 void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) {
1426 HBinaryOperation* hdiv = instr->hydrogen();
1427 Register dividend = ToRegister(instr->dividend());
1428 Register divisor = ToRegister(instr->divisor());
1429 const Register result = ToRegister(instr->result());
1437 DeoptimizeIf(eq, instr, divisor, Operand(zero_reg));
1444 DeoptimizeIf(lt, instr, divisor, Operand(zero_reg));
1453 DeoptimizeIf(eq, instr, divisor, Operand(-1));
1467 void LCodeGen::DoMulI(LMulI* instr) {
1469 Register result = ToRegister(instr->result());
1471 Register left = ToRegister(instr->left());
1472 LOperand* right_op = instr->right();
1475 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
1476 bool overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1484 DeoptimizeIf(eq, instr, left, Operand(zero_reg));
1491 DeoptimizeIf(lt, instr, scratch, Operand(zero_reg));
1500 DeoptimizeIf(lt, instr, left, Operand(zero_reg));
1545 if (instr->hydrogen()->representation().IsSmi()) {
1552 DeoptimizeIf(ne, instr, scratch, Operand(at));
1554 if (instr->hydrogen()->representation().IsSmi()) {
1567 DeoptimizeIf(eq, instr, result, Operand(zero_reg));
1574 void LCodeGen::DoBitI(LBitI* instr) {
1575 LOperand* left_op = instr->left();
1576 LOperand* right_op = instr->right();
1579 Register result = ToRegister(instr->result());
1589 switch (instr->op()) {
1610 void LCodeGen::DoShiftI(LShiftI* instr) {
1613 LOperand* right_op = instr->right();
1614 Register left = ToRegister(instr->left());
1615 Register result = ToRegister(instr->result());
1621 switch (instr->op()) {
1630 if (instr->can_deopt()) {
1631 DeoptimizeIf(lt, instr, result, Operand(zero_reg));
1645 switch (instr->op()) {
1664 if (instr->can_deopt()) {
1666 DeoptimizeIf(ne, instr, at, Operand(zero_reg));
1673 if (instr->hydrogen_value()->representation().IsSmi() &&
1674 instr->can_deopt()) {
1681 DeoptimizeIf(lt, instr, scratch, Operand(zero_reg));
1697 void LCodeGen::DoSubI(LSubI* instr) {
1698 LOperand* left = instr->left();
1699 LOperand* right = instr->right();
1700 LOperand* result = instr->result();
1701 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1729 DeoptimizeIf(lt, instr, overflow, Operand(zero_reg));
1734 void LCodeGen::DoConstantI(LConstantI* instr) {
1735 __ li(ToRegister(instr->result()), Operand(instr->value()));
1739 void LCodeGen::DoConstantS(LConstantS* instr) {
1740 __ li(ToRegister(instr->result()), Operand(instr->value()));
1744 void LCodeGen::DoConstantD(LConstantD* instr) {
1745 DCHECK(instr->result()->IsDoubleRegister());
1746 DoubleRegister result = ToDoubleRegister(instr->result());
1747 double v = instr->value();
1752 void LCodeGen::DoConstantE(LConstantE* instr) {
1753 __ li(ToRegister(instr->result()), Operand(instr->value()));
1757 void LCodeGen::DoConstantT(LConstantT* instr) {
1758 Handle<Object> object = instr->value(isolate());
1760 __ li(ToRegister(instr->result()), object);
1764 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1765 Register result = ToRegister(instr->result());
1766 Register map = ToRegister(instr->value());
1771 void LCodeGen::DoDateField(LDateField* instr) {
1772 Register object = ToRegister(instr->date());
1773 Register result = ToRegister(instr->result());
1774 Register scratch = ToRegister(instr->temp());
1775 Smi* index = instr->index();
1783 DeoptimizeIf(eq, instr, at, Operand(zero_reg));
1785 DeoptimizeIf(ne, instr, scratch, Operand(JS_DATE_TYPE));
1834 void LCodeGen::DoSeqStringGetChar(LSeqStringGetChar* instr) {
1835 String::Encoding encoding = instr->hydrogen()->encoding();
1836 Register string = ToRegister(instr->string());
1837 Register result = ToRegister(instr->result());
1853 MemOperand operand = BuildSeqStringOperand(string, instr->index(), encoding);
1862 void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
1863 String::Encoding encoding = instr->hydrogen()->encoding();
1864 Register string = ToRegister(instr->string());
1865 Register value = ToRegister(instr->value());
1869 Register index = ToRegister(instr->index());
1873 instr->hydrogen()->encoding() == String::ONE_BYTE_ENCODING
1878 MemOperand operand = BuildSeqStringOperand(string, instr->index(), encoding);
1887 void LCodeGen::DoAddI(LAddI* instr) {
1888 LOperand* left = instr->left();
1889 LOperand* right = instr->right();
1890 LOperand* result = instr->result();
1891 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1920 DeoptimizeIf(lt, instr, overflow, Operand(zero_reg));
1925 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
1926 LOperand* left = instr->left();
1927 LOperand* right = instr->right();
1928 HMathMinMax::Operation operation = instr->hydrogen()->operation();
1930 if (instr->hydrogen()->representation().IsSmiOrInteger32()) {
1933 Register result_reg = ToRegister(instr->result());
1946 DCHECK(instr->hydrogen()->representation().IsDouble());
1949 FPURegister result_reg = ToDoubleRegister(instr->result());
1986 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1987 DoubleRegister left = ToDoubleRegister(instr->left());
1988 DoubleRegister right = ToDoubleRegister(instr->right());
1989 DoubleRegister result = ToDoubleRegister(instr->result());
1990 switch (instr->op()) {
2027 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
2028 DCHECK(ToRegister(instr->context()).is(cp));
2029 DCHECK(ToRegister(instr->left()).is(a1));
2030 DCHECK(ToRegister(instr->right()).is(a0));
2031 DCHECK(ToRegister(instr->result()).is(v0));
2034 CodeFactory::BinaryOpIC(isolate(), instr->op(), NO_OVERWRITE).code();
2035 CallCode(code, RelocInfo::CODE_TARGET, instr);
2043 void LCodeGen::EmitBranch(InstrType instr,
2047 int left_block = instr->TrueDestination(chunk_);
2048 int right_block = instr->FalseDestination(chunk_);
2066 void LCodeGen::EmitBranchF(InstrType instr,
2070 int right_block = instr->FalseDestination(chunk_);
2071 int left_block = instr->TrueDestination(chunk_);
2091 void LCodeGen::EmitFalseBranch(InstrType instr,
2095 int false_block = instr->FalseDestination(chunk_);
2101 void LCodeGen::EmitFalseBranchF(InstrType instr,
2105 int false_block = instr->FalseDestination(chunk_);
2111 void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
2116 void LCodeGen::DoBranch(LBranch* instr) {
2117 Representation r = instr->hydrogen()->value()->representation();
2120 Register reg = ToRegister(instr->value());
2121 EmitBranch(instr, ne, reg, Operand(zero_reg));
2124 DoubleRegister reg = ToDoubleRegister(instr->value());
2126 EmitBranchF(instr, nue, reg, kDoubleRegZero);
2129 Register reg = ToRegister(instr->value());
2130 HType type = instr->hydrogen()->value()->type();
2134 EmitBranch(instr, eq, reg, Operand(at));
2137 EmitBranch(instr, ne, reg, Operand(zero_reg));
2140 EmitBranch(instr, al, zero_reg, Operand(zero_reg));
2146 EmitBranchF(instr, nue, dbl_scratch, kDoubleRegZero);
2150 EmitBranch(instr, ne, at, Operand(zero_reg));
2152 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
2159 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at));
2164 __ Branch(instr->TrueLabel(chunk_), eq, reg, Operand(at));
2166 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at));
2171 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at));
2176 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(zero_reg));
2177 __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
2181 DeoptimizeIf(eq, instr, at, Operand(zero_reg));
2191 __ Branch(instr->FalseLabel(chunk_), ne, at, Operand(zero_reg));
2198 __ Branch(instr->TrueLabel(chunk_),
2208 __ Branch(instr->TrueLabel(chunk_), ne, at, Operand(zero_reg));
2209 __ Branch(instr->FalseLabel(chunk_));
2217 __ Branch(instr->TrueLabel(chunk_), eq, scratch, Operand(SYMBOL_TYPE));
2227 __ BranchF(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
2230 __ Branch(instr->FalseLabel(chunk_));
2237 DeoptimizeIf(al, instr, zero_reg, Operand(zero_reg));
2251 void LCodeGen::DoGoto(LGoto* instr) {
2252 EmitGoto(instr->block_id());
2288 void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) {
2289 LOperand* left = instr->left();
2290 LOperand* right = instr->right();
2292 instr->hydrogen()->left()->CheckFlag(HInstruction::kUint32) ||
2293 instr->hydrogen()->right()->CheckFlag(HInstruction::kUint32);
2294 Condition cond = TokenToCondition(instr->op(), is_unsigned);
2300 int next_block = EvalComparison(instr->op(), left_val, right_val) ?
2301 instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_);
2304 if (instr->is_double()) {
2312 __ BranchF(NULL, instr->FalseLabel(chunk_), eq,
2315 EmitBranchF(instr, cond, left_reg, right_reg);
2322 if (instr->hydrogen_value()->representation().IsSmi()) {
2331 if (instr->hydrogen_value()->representation().IsSmi()) {
2345 EmitBranch(instr, cond, cmp_left, cmp_right);
2351 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
2352 Register left = ToRegister(instr->left());
2353 Register right = ToRegister(instr->right());
2355 EmitBranch(instr, eq, left, Operand(right));
2359 void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
2360 if (instr->hydrogen()->representation().IsTagged()) {
2361 Register input_reg = ToRegister(instr->object());
2363 EmitBranch(instr, eq, input_reg, Operand(at));
2367 DoubleRegister input_reg = ToDoubleRegister(instr->object());
2368 EmitFalseBranchF(instr, eq, input_reg, input_reg);
2372 EmitBranch(instr, eq, scratch, Operand(kHoleNanUpper32));
2376 void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
2377 Representation rep = instr->hydrogen()->value()->representation();
2379 Register scratch = ToRegister(instr->temp());
2382 DoubleRegister value = ToDoubleRegister(instr->value());
2383 EmitFalseBranchF(instr, ne, value, kDoubleRegZero);
2387 Register value = ToRegister(instr->value());
2391 instr->FalseLabel(chunk()),
2394 EmitFalseBranch(instr, ne, scratch, Operand(0x80000000));
2398 EmitBranch(instr, eq, scratch, Operand(at));
2428 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
2429 Register reg = ToRegister(instr->value());
2430 Register temp1 = ToRegister(instr->temp());
2435 instr->FalseLabel(chunk_), instr->TrueLabel(chunk_));
2437 EmitBranch(instr, true_cond, temp2,
2455 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
2456 Register reg = ToRegister(instr->value());
2457 Register temp1 = ToRegister(instr->temp());
2460 instr->hydrogen()->value()->type().IsHeapObject()
2463 EmitIsString(reg, temp1, instr->FalseLabel(chunk_), check_needed);
2465 EmitBranch(instr, true_cond, temp1,
2470 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
2471 Register input_reg = EmitLoadRegister(instr->value(), at);
2473 EmitBranch(instr, eq, at, Operand(zero_reg));
2477 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
2478 Register input = ToRegister(instr->value());
2479 Register temp = ToRegister(instr->temp());
2481 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
2482 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2487 EmitBranch(instr, ne, at, Operand(zero_reg));
2511 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
2512 DCHECK(ToRegister(instr->context()).is(cp));
2513 Token::Value op = instr->op();
2516 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2520 EmitBranch(instr, condition, v0, Operand(zero_reg));
2524 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
2525 InstanceType from = instr->from();
2526 InstanceType to = instr->to();
2533 static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
2534 InstanceType from = instr->from();
2535 InstanceType to = instr->to();
2544 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
2546 Register input = ToRegister(instr->value());
2548 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
2549 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2553 EmitBranch(instr,
2554 BranchCondition(instr->hydrogen()),
2556 Operand(TestType(instr->hydrogen())));
2560 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
2561 Register input = ToRegister(instr->value());
2562 Register result = ToRegister(instr->result());
2572 LHasCachedArrayIndexAndBranch* instr) {
2573 Register input = ToRegister(instr->value());
2579 EmitBranch(instr, eq, at, Operand(zero_reg));
2649 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2650 Register input = ToRegister(instr->value());
2652 Register temp2 = ToRegister(instr->temp());
2653 Handle<String> class_name = instr->hydrogen()->class_name();
2655 EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
2658 EmitBranch(instr, eq, temp, Operand(class_name));
2662 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
2663 Register reg = ToRegister(instr->value());
2664 Register temp = ToRegister(instr->temp());
2667 EmitBranch(instr, eq, temp, Operand(instr->map()));
2671 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
2672 DCHECK(ToRegister(instr->context()).is(cp));
2674 DCHECK(ToRegister(instr->left()).is(a0)); // Object is in a0.
2675 DCHECK(ToRegister(instr->right()).is(a1)); // Function is in a1.
2676 Register result = ToRegister(instr->result());
2680 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2691 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
2695 LInstanceOfKnownGlobal* instr)
2696 : LDeferredCode(codegen), instr_(instr) { }
2700 virtual LInstruction* instr() OVERRIDE { return instr_; }
2709 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
2712 Register object = ToRegister(instr->value());
2713 Register temp = ToRegister(instr->temp());
2714 Register result = ToRegister(instr->result());
2768 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
2770 Register result = ToRegister(instr->result());
2783 LoadContextFromDeferred(instr->context());
2788 Register temp = ToRegister(instr->temp());
2790 __ li(InstanceofStub::right(), instr->function());
2802 instr,
2804 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment();
2812 void LCodeGen::DoCmpT(LCmpT* instr) {
2813 DCHECK(ToRegister(instr->context()).is(cp));
2814 Token::Value op = instr->op();
2817 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2827 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex);
2829 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
2834 void LCodeGen::DoReturn(LReturn* instr) {
2853 if (instr->has_constant_parameter_count()) {
2854 int parameter_count = ToInteger32(instr->constant_parameter_count());
2860 Register reg = ToRegister(instr->parameter_count());
2875 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
2876 Register result = ToRegister(instr->result());
2877 __ li(at, Operand(Handle<Object>(instr->hydrogen()->cell().handle())));
2879 if (instr->hydrogen()->RequiresHoleCheck()) {
2881 DeoptimizeIf(eq, instr, result, Operand(at));
2887 void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
2889 Register vector = ToRegister(instr->temp_vector());
2891 __ li(vector, instr->hydrogen()->feedback_vector());
2895 Operand(Smi::FromInt(instr->hydrogen()->slot())));
2899 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
2900 DCHECK(ToRegister(instr->context()).is(cp));
2901 DCHECK(ToRegister(instr->global_object())
2903 DCHECK(ToRegister(instr->result()).is(v0));
2905 __ li(LoadDescriptor::NameRegister(), Operand(instr->name()));
2907 EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
2909 ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
2911 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2915 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
2916 Register value = ToRegister(instr->value());
2920 __ li(cell, Operand(instr->hydrogen()->cell().handle()));
2926 if (instr->hydrogen()->RequiresHoleCheck()) {
2928 Register payload = ToRegister(instr->temp());
2931 DeoptimizeIf(eq, instr, payload, Operand(at));
2941 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
2942 Register context = ToRegister(instr->context());
2943 Register result = ToRegister(instr->result());
2945 __ lw(result, ContextOperand(context, instr->slot_index()));
2946 if (instr->hydrogen()->RequiresHoleCheck()) {
2949 if (instr->hydrogen()->DeoptimizesOnHole()) {
2950 DeoptimizeIf(eq, instr, result, Operand(at));
2961 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
2962 Register context = ToRegister(instr->context());
2963 Register value = ToRegister(instr->value());
2965 MemOperand target = ContextOperand(context, instr->slot_index());
2969 if (instr->hydrogen()->RequiresHoleCheck()) {
2973 if (instr->hydrogen()->DeoptimizesOnHole()) {
2974 DeoptimizeIf(eq, instr, scratch, Operand(at));
2981 if (instr->hydrogen()->NeedsWriteBarrier()) {
2983 instr->hydrogen()->value()->type().IsHeapObject()
2999 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
3000 HObjectAccess access = instr->hydrogen()->access();
3002 Register object = ToRegister(instr->object());
3005 Register result = ToRegister(instr->result());
3011 if (instr->hydrogen()->representation().IsDouble()) {
3012 DoubleRegister result = ToDoubleRegister(instr->result());
3017 Register result = ToRegister(instr->result());
3027 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
3028 DCHECK(ToRegister(instr->context()).is(cp));
3029 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister()));
3030 DCHECK(ToRegister(instr->result()).is(v0));
3033 __ li(LoadDescriptor::NameRegister(), Operand(instr->name()));
3035 EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
3038 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3042 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
3044 Register function = ToRegister(instr->function());
3045 Register result = ToRegister(instr->result());
3053 DeoptimizeIf(eq, instr, result, Operand(at));
3068 void LCodeGen::DoLoadRoot(LLoadRoot* instr) {
3069 Register result = ToRegister(instr->result());
3070 __ LoadRoot(result, instr->index());
3074 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
3075 Register arguments = ToRegister(instr->arguments());
3076 Register result = ToRegister(instr->result());
3079 if (instr->length()->IsConstantOperand()) {
3080 int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
3081 if (instr->index()->IsConstantOperand()) {
3082 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3086 Register index = ToRegister(instr->index());
3093 } else if (instr->index()->IsConstantOperand()) {
3094 Register length = ToRegister(instr->length());
3095 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3108 Register length = ToRegister(instr->length());
3109 Register index = ToRegister(instr->index());
3119 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
3120 Register external_pointer = ToRegister(instr->elements());
3122 ElementsKind elements_kind = instr->elements_kind();
3123 bool key_is_constant = instr->key()->IsConstantOperand();
3126 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
3131 key = ToRegister(instr->key());
3134 int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
3136 int base_offset = instr->base_offset();
3142 int base_offset = instr->base_offset();
3143 FPURegister result = ToDoubleRegister(instr->result());
3158 Register result = ToRegister(instr->result());
3188 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
3189 DeoptimizeIf(Ugreater_equal, instr, result, Operand(0x80000000));
3211 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
3212 Register elements = ToRegister(instr->elements());
3213 bool key_is_constant = instr->key()->IsConstantOperand();
3215 DoubleRegister result = ToDoubleRegister(instr->result());
3220 int base_offset = instr->base_offset();
3222 int constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
3231 key = ToRegister(instr->key());
3232 int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
3240 if (instr->hydrogen()->RequiresHoleCheck()) {
3242 DeoptimizeIf(eq, instr, scratch, Operand(kHoleNanUpper32));
3247 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3248 Register elements = ToRegister(instr->elements());
3249 Register result = ToRegister(instr->result());
3252 int offset = instr->base_offset();
3254 if (instr->key()->IsConstantOperand()) {
3255 LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
3259 Register key = ToRegister(instr->key());
3264 if (instr->hydrogen()->key()->representation().IsSmi()) {
3275 if (instr->hydrogen()->RequiresHoleCheck()) {
3276 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
3278 DeoptimizeIf(ne, instr, scratch, Operand(zero_reg));
3281 DeoptimizeIf(eq, instr, result, Operand(scratch));
3287 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
3288 if (instr->is_typed_elements()) {
3289 DoLoadKeyedExternalArray(instr);
3290 } else if (instr->hydrogen()->representation().IsDouble()) {
3291 DoLoadKeyedFixedDoubleArray(instr);
3293 DoLoadKeyedFixedArray(instr);
3335 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
3336 DCHECK(ToRegister(instr->context()).is(cp));
3337 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister()));
3338 DCHECK(ToRegister(instr->key()).is(LoadDescriptor::NameRegister()));
3341 EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
3345 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3349 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
3352 Register result = ToRegister(instr->result());
3354 if (instr->hydrogen()->from_inlined()) {
3371 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
3372 Register elem = ToRegister(instr->elements());
3373 Register result = ToRegister(instr->result());
3392 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
3393 Register receiver = ToRegister(instr->receiver());
3394 Register function = ToRegister(instr->function());
3395 Register result = ToRegister(instr->result());
3403 if (!instr->hydrogen()->known_function()) {
3427 DeoptimizeIf(eq, instr, scratch, Operand(zero_reg));
3430 DeoptimizeIf(lt, instr, scratch, Operand(FIRST_SPEC_OBJECT_TYPE));
3452 void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
3453 Register receiver = ToRegister(instr->receiver());
3454 Register function = ToRegister(instr->function());
3455 Register length = ToRegister(instr->length());
3456 Register elements = ToRegister(instr->elements());
3460 DCHECK(ToRegister(instr->result()).is(v0));
3465 DeoptimizeIf(hi, instr, length, Operand(kArgumentsLimit));
3489 DCHECK(instr->HasPointerMap());
3490 LPointerMap* pointers = instr->pointer_map();
3500 void LCodeGen::DoPushArgument(LPushArgument* instr) {
3501 LOperand* argument = instr->value();
3511 void LCodeGen::DoDrop(LDrop* instr) {
3512 __ Drop(instr->count());
3516 void LCodeGen::DoThisFunction(LThisFunction* instr) {
3517 Register result = ToRegister(instr->result());
3522 void LCodeGen::DoContext(LContext* instr) {
3524 Register result = ToRegister(instr->result());
3534 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
3535 DCHECK(ToRegister(instr->context()).is(cp));
3536 __ li(scratch0(), instr->hydrogen()->pairs());
3537 __ li(scratch1(), Operand(Smi::FromInt(instr->hydrogen()->flags())));
3540 CallRuntime(Runtime::kDeclareGlobals, 3, instr);
3547 LInstruction* instr,
3554 LPointerMap* pointers = instr->pointer_map();
3575 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
3585 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3586 DCHECK(instr->context() != NULL);
3587 DCHECK(ToRegister(instr->context()).is(cp));
3588 Register input = ToRegister(instr->value());
3589 Register result = ToRegister(instr->result());
3595 DeoptimizeIf(ne, instr, scratch, Operand(at));
3629 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr,
3630 instr->context());
3653 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
3654 Register input = ToRegister(instr->value());
3655 Register result = ToRegister(instr->result());
3662 DeoptimizeIf(lt, instr, result, Operand(zero_reg));
3667 void LCodeGen::DoMathAbs(LMathAbs* instr) {
3671 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr)
3672 : LDeferredCode(codegen), instr_(instr) { }
3676 virtual LInstruction* instr() OVERRIDE { return instr_; }
3681 Representation r = instr->hydrogen()->value()->representation();
3683 FPURegister input = ToDoubleRegister(instr->value());
3684 FPURegister result = ToDoubleRegister(instr->result());
3687 EmitIntegerMathAbs(instr);
3691 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
3692 Register input = ToRegister(instr->value());
3696 EmitIntegerMathAbs(instr);
3702 void LCodeGen::DoMathFloor(LMathFloor* instr) {
3703 DoubleRegister input = ToDoubleRegister(instr->value());
3704 Register result = ToRegister(instr->result());
3706 Register except_flag = ToRegister(instr->temp());
3716 DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg));
3718 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3724 DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg));
3730 void LCodeGen::DoMathRound(LMathRound* instr) {
3731 DoubleRegister input = ToDoubleRegister(instr->value());
3732 Register result = ToRegister(instr->result());
3733 DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp());
3748 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3757 DeoptimizeIf(ge, instr, scratch, Operand(HeapNumber::kExponentBias + 32));
3769 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3771 DeoptimizeIf(lt, instr, result, Operand(zero_reg));
3790 DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg));
3792 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3798 DeoptimizeIf(ne, instr, scratch, Operand(zero_reg));
3804 void LCodeGen::DoMathFround(LMathFround* instr) {
3805 DoubleRegister input = ToDoubleRegister(instr->value());
3806 DoubleRegister result = ToDoubleRegister(instr->result());
3812 void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
3813 DoubleRegister input = ToDoubleRegister(instr->value());
3814 DoubleRegister result = ToDoubleRegister(instr->result());
3819 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
3820 DoubleRegister input = ToDoubleRegister(instr->value());
3821 DoubleRegister result = ToDoubleRegister(instr->result());
3822 DoubleRegister temp = ToDoubleRegister(instr->temp());
3843 void LCodeGen::DoPower(LPower* instr) {
3844 Representation exponent_type = instr->hydrogen()->right()->representation();
3848 DCHECK(!instr->right()->IsDoubleRegister() ||
3849 ToDoubleRegister(instr->right()).is(f4));
3850 DCHECK(!instr->right()->IsRegister() ||
3851 ToRegister(instr->right()).is(tagged_exponent));
3852 DCHECK(ToDoubleRegister(instr->left()).is(f2));
3853 DCHECK(ToDoubleRegister(instr->result()).is(f0));
3864 DeoptimizeIf(ne, instr, t3, Operand(at));
3879 void LCodeGen::DoMathExp(LMathExp* instr) {
3880 DoubleRegister input = ToDoubleRegister(instr->value());
3881 DoubleRegister result = ToDoubleRegister(instr->result());
3882 DoubleRegister double_scratch1 = ToDoubleRegister(instr->double_temp());
3884 Register temp1 = ToRegister(instr->temp1());
3885 Register temp2 = ToRegister(instr->temp2());
3893 void LCodeGen::DoMathLog(LMathLog* instr) {
3895 __ MovToFloatParameter(ToDoubleRegister(instr->value()));
3898 __ MovFromFloatResult(ToDoubleRegister(instr->result()));
3902 void LCodeGen::DoMathClz32(LMathClz32* instr) {
3903 Register input = ToRegister(instr->value());
3904 Register result = ToRegister(instr->result());
3909 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
3910 DCHECK(ToRegister(instr->context()).is(cp));
3911 DCHECK(ToRegister(instr->function()).is(a1));
3912 DCHECK(instr->HasPointerMap());
3914 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
3916 LPointerMap* pointers = instr->pointer_map();
3918 ParameterCount count(instr->arity());
3922 instr->hydrogen()->formal_parameter_count(),
3923 instr->arity(),
3924 instr,
3931 LTailCallThroughMegamorphicCache* instr) {
3932 Register receiver = ToRegister(instr->receiver());
3933 Register name = ToRegister(instr->name());
3948 isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(),
3958 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
3959 DCHECK(ToRegister(instr->result()).is(v0));
3961 LPointerMap* pointers = instr->pointer_map();
3964 if (instr->target()->IsConstantOperand()) {
3965 LConstantOperand* target = LConstantOperand::cast(instr->target());
3970 DCHECK(instr->target()->IsRegister());
3971 Register target = ToRegister(instr->target());
3980 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) {
3981 DCHECK(ToRegister(instr->function()).is(a1));
3982 DCHECK(ToRegister(instr->result()).is(v0));
3984 if (instr->hydrogen()->pass_argument_count()) {
3985 __ li(a0, Operand(instr->arity()));
3995 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
3999 void LCodeGen::DoCallFunction(LCallFunction* instr) {
4000 DCHECK(ToRegister(instr->context()).is(cp));
4001 DCHECK(ToRegister(instr->function()).is(a1));
4002 DCHECK(ToRegister(instr->result()).is(v0));
4004 int arity = instr->arity();
4005 CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
4006 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
4010 void LCodeGen::DoCallNew(LCallNew* instr) {
4011 DCHECK(ToRegister(instr->context()).is(cp));
4012 DCHECK(ToRegister(instr->constructor()).is(a1));
4013 DCHECK(ToRegister(instr->result()).is(v0));
4015 __ li(a0, Operand(instr->arity()));
4019 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
4023 void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
4024 DCHECK(ToRegister(instr->context()).is(cp));
4025 DCHECK(ToRegister(instr->constructor()).is(a1));
4026 DCHECK(ToRegister(instr->result()).is(v0));
4028 __ li(a0, Operand(instr->arity()));
4030 ElementsKind kind = instr->hydrogen()->elements_kind();
4036 if (instr->arity() == 0) {
4038 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
4039 } else if (instr->arity() == 1) {
4052 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
4058 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
4062 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
4067 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
4068 CallRuntime(instr->function(), instr->arity(), instr);
4072 void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) {
4073 Register function = ToRegister(instr->function());
4074 Register code_object = ToRegister(instr->code_object());
4082 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
4083 Register result = ToRegister(instr->result());
4084 Register base = ToRegister(instr->base_object());
4085 if (instr->offset()->IsConstantOperand()) {
4086 LConstantOperand* offset = LConstantOperand::cast(instr->offset());
4089 Register offset = ToRegister(instr->offset());
4095 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
4096 Representation representation = instr->representation();
4098 Register object = ToRegister(instr->object());
4100 HObjectAccess access = instr->hydrogen()->access();
4104 Register value = ToRegister(instr->value());
4113 !instr->value()->IsConstantOperand() ||
4114 IsSmi(LConstantOperand::cast(instr->value())));
4117 DCHECK(!instr->hydrogen()->has_transition());
4118 DCHECK(!instr->hydrogen()->NeedsWriteBarrier());
4119 DoubleRegister value = ToDoubleRegister(instr->value());
4124 if (instr->hydrogen()->has_transition()) {
4125 Handle<Map> transition = instr->hydrogen()->transition_map();
4129 if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
4130 Register temp = ToRegister(instr->temp());
4141 Register value = ToRegister(instr->value());
4145 if (instr->hydrogen()->NeedsWriteBarrier()) {
4154 instr->hydrogen()->SmiCheckForWriteBarrier(),
4155 instr->hydrogen()->PointersToHereCheckForValue());
4161 if (instr->hydrogen()->NeedsWriteBarrier()) {
4171 instr->hydrogen()->SmiCheckForWriteBarrier(),
4172 instr->hydrogen()->PointersToHereCheckForValue());
4178 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
4179 DCHECK(ToRegister(instr->context()).is(cp));
4180 DCHECK(ToRegister(instr->object()).is(StoreDescriptor::ReceiverRegister()));
4181 DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister()));
4183 __ li(StoreDescriptor::NameRegister(), Operand(instr->name()));
4184 Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode());
4185 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4189 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
4190 Condition cc = instr->hydrogen()->allow_equality() ? hi : hs;
4193 if (instr->index()->IsConstantOperand()) {
4194 operand = ToOperand(instr->index());
4195 reg = ToRegister(instr->length());
4198 reg = ToRegister(instr->index());
4199 operand = ToOperand(instr->length());
4201 if (FLAG_debug_code && instr->hydrogen()->skip_check()) {
4207 DeoptimizeIf(cc, instr, reg, operand);
4212 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4213 Register external_pointer = ToRegister(instr->elements());
4215 ElementsKind elements_kind = instr->elements_kind();
4216 bool key_is_constant = instr->key()->IsConstantOperand();
4219 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
4224 key = ToRegister(instr->key());
4227 int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
4229 int base_offset = instr->base_offset();
4236 FPURegister value(ToDoubleRegister(instr->value()));
4257 Register value(ToRegister(instr->value()));
4302 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
4303 DoubleRegister value = ToDoubleRegister(instr->value());
4304 Register elements = ToRegister(instr->elements());
4307 bool key_is_constant = instr->key()->IsConstantOperand();
4308 int base_offset = instr->base_offset();
4315 int constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
4322 int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
4325 __ sll(at, ToRegister(instr->key()), shift_size);
4329 if (instr->NeedsCanonicalization()) {
4349 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4350 Register value = ToRegister(instr->value());
4351 Register elements = ToRegister(instr->elements());
4352 Register key = instr->key()->IsRegister() ? ToRegister(instr->key())
4356 int offset = instr->base_offset();
4359 if (instr->key()->IsConstantOperand()) {
4360 DCHECK(!instr->hydrogen()->NeedsWriteBarrier());
4361 LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
4369 if (instr->hydrogen()->key()->representation().IsSmi()) {
4379 if (instr->hydrogen()->NeedsWriteBarrier()) {
4381 instr->hydrogen()->value()->type().IsHeapObject()
4392 instr->hydrogen()->PointersToHereCheckForValue());
4397 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
4399 if (instr->is_typed_elements()) {
4400 DoStoreKeyedExternalArray(instr);
4401 } else if (instr->hydrogen()->value()->representation().IsDouble()) {
4402 DoStoreKeyedFixedDoubleArray(instr);
4404 DoStoreKeyedFixedArray(instr);
4409 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
4410 DCHECK(ToRegister(instr->context()).is(cp));
4411 DCHECK(ToRegister(instr->object()).is(StoreDescriptor::ReceiverRegister()));
4412 DCHECK(ToRegister(instr->key()).is(StoreDescriptor::NameRegister()));
4413 DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister()));
4416 CodeFactory::KeyedStoreIC(isolate(), instr->strict_mode()).code();
4417 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4421 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
4422 Register object_reg = ToRegister(instr->object());
4425 Handle<Map> from_map = instr->original_map();
4426 Handle<Map> to_map = instr->transitioned_map();
4427 ElementsKind from_kind = instr->from_kind();
4428 ElementsKind to_kind = instr->to_kind();
4435 Register new_map_reg = ToRegister(instr->new_map_temp());
4446 DCHECK(ToRegister(instr->context()).is(cp));
4453 instr->pointer_map(), 0, Safepoint::kLazyDeopt);
4459 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
4460 Register object = ToRegister(instr->object());
4461 Register temp = ToRegister(instr->temp());
4465 DeoptimizeIf(al, instr);
4470 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4471 DCHECK(ToRegister(instr->context()).is(cp));
4472 DCHECK(ToRegister(instr->left()).is(a1));
4473 DCHECK(ToRegister(instr->right()).is(a0));
4475 instr->hydrogen()->flags(),
4476 instr->hydrogen()->pretenure_flag());
4477 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
4481 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
4484 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
4485 : LDeferredCode(codegen), instr_(instr) { }
4489 virtual LInstruction* instr() OVERRIDE { return instr_; }
4495 new(zone()) DeferredStringCharCodeAt(this, instr);
4497 ToRegister(instr->string()),
4498 ToRegister(instr->index()),
4499 ToRegister(instr->result()),
4505 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
4506 Register string = ToRegister(instr->string());
4507 Register result = ToRegister(instr->result());
4519 if (instr->index()->IsConstantOperand()) {
4520 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
4524 Register index = ToRegister(instr->index());
4528 CallRuntimeFromDeferred(Runtime::kStringCharCodeAtRT, 2, instr,
4529 instr->context());
4536 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
4539 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
4540 : LDeferredCode(codegen), instr_(instr) { }
4544 virtual LInstruction* instr() OVERRIDE { return instr_; }
4550 new(zone()) DeferredStringCharFromCode(this, instr);
4552 DCHECK(instr->hydrogen()->value()->representation().IsInteger32());
4553 Register char_code = ToRegister(instr->char_code());
4554 Register result = ToRegister(instr->result());
4570 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
4571 Register char_code = ToRegister(instr->char_code());
4572 Register result = ToRegister(instr->result());
4582 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context());
4587 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4588 LOperand* input = instr->value();
4590 LOperand* output = instr->result();
4604 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4605 LOperand* input = instr->value();
4606 LOperand* output = instr->result();
4614 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4617 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
4618 : LDeferredCode(codegen), instr_(instr) { }
4626 virtual LInstruction* instr() OVERRIDE { return instr_; }
4631 Register src = ToRegister(instr->value());
4632 Register dst = ToRegister(instr->result());
4635 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr);
4642 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4645 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
4646 : LDeferredCode(codegen), instr_(instr) { }
4654 virtual LInstruction* instr() OVERRIDE { return instr_; }
4659 Register input = ToRegister(instr->value());
4660 Register result = ToRegister(instr->result());
4662 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4669 void LCodeGen::DoDeferredNumberTagIU(LInstruction* instr,
4676 Register dst = ToRegister(instr->result());
4722 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4736 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
4739 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4740 : LDeferredCode(codegen), instr_(instr) { }
4744 virtual LInstruction* instr() OVERRIDE { return instr_; }
4749 DoubleRegister input_reg = ToDoubleRegister(instr->value());
4751 Register reg = ToRegister(instr->result());
4752 Register temp1 = ToRegister(instr->temp());
4753 Register temp2 = ToRegister(instr->temp2());
4755 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4771 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
4775 Register reg = ToRegister(instr->result());
4787 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4793 void LCodeGen::DoSmiTag(LSmiTag* instr) {
4794 HChange* hchange = instr->hydrogen();
4795 Register input = ToRegister(instr->value());
4796 Register output = ToRegister(instr->result());
4800 DeoptimizeIf(ne, instr, at, Operand(zero_reg));
4805 DeoptimizeIf(lt, instr, at, Operand(zero_reg));
4812 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
4814 Register input = ToRegister(instr->value());
4815 Register result = ToRegister(instr->result());
4816 if (instr->needs_check()) {
4821 DeoptimizeIf(ne, instr, scratch, Operand(zero_reg));
4828 void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg,
4832 instr->hydrogen()->can_convert_undefined_to_nan();
4833 bool deoptimize_on_minus_zero = instr->hydrogen()->deoptimize_on_minus_zero();
4846 DeoptimizeIf(ne, instr, scratch, Operand(at));
4854 DeoptimizeIf(eq, instr, scratch, Operand(HeapNumber::kSignMask));
4861 DeoptimizeIf(ne, instr, input_reg, Operand(at));
4879 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
4880 Register input_reg = ToRegister(instr->value());
4882 Register scratch2 = ToRegister(instr->temp());
4884 DoubleRegister double_scratch2 = ToDoubleRegister(instr->temp2());
4898 if (instr->truncating()) {
4913 DCHECK(ToRegister(instr->result()).is(input_reg));
4925 DeoptimizeIf(ne, instr, scratch2, Operand(at), "cannot truncate");
4929 DeoptimizeIf(ne, instr, scratch1, Operand(at), "not a heap number");
4944 DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg),
4947 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
4952 DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg), "minus zero");
4959 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
4962 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
4963 : LDeferredCode(codegen), instr_(instr) { }
4967 virtual LInstruction* instr() OVERRIDE { return instr_; }
4972 LOperand* input = instr->value();
4974 DCHECK(input->Equals(instr->result()));
4978 if (instr->hydrogen()->value()->representation().IsSmi()) {
4981 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
4993 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
4994 LOperand* input = instr->value();
4996 LOperand* result = instr->result();
5002 HValue* value = instr->hydrogen()->value();
5006 EmitNumberUntagD(instr, input_reg, result_reg, mode);
5010 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
5011 Register result_reg = ToRegister(instr->result());
5013 DoubleRegister double_input = ToDoubleRegister(instr->value());
5015 if (instr->truncating()) {
5029 DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg));
5031 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5036 DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg));
5043 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
5044 Register result_reg = ToRegister(instr->result());
5046 DoubleRegister double_input = ToDoubleRegister(instr->value());
5048 if (instr->truncating()) {
5062 DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg));
5064 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5069 DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg));
5074 DeoptimizeIf(lt, instr, scratch1, Operand(zero_reg));
5078 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
5079 LOperand* input = instr->value();
5081 DeoptimizeIf(ne, instr, at, Operand(zero_reg));
5085 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
5086 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
5087 LOperand* input = instr->value();
5089 DeoptimizeIf(eq, instr, at, Operand(zero_reg));
5094 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
5095 Register input = ToRegister(instr->value());
5100 if (instr->hydrogen()->is_interval_check()) {
5103 instr->hydrogen()->GetCheckInterval(&first, &last);
5107 DeoptimizeIf(ne, instr, scratch, Operand(first));
5109 DeoptimizeIf(lo, instr, scratch, Operand(first));
5112 DeoptimizeIf(hi, instr, scratch, Operand(last));
5118 instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
5123 DeoptimizeIf(tag == 0 ? ne : eq, instr, at, Operand(zero_reg));
5126 DeoptimizeIf(ne, instr, scratch, Operand(tag));
5132 void LCodeGen::DoCheckValue(LCheckValue* instr) {
5133 Register reg = ToRegister(instr->value());
5134 Handle<HeapObject> object = instr->hydrogen()->object().handle();
5137 Register reg = ToRegister(instr->value());
5141 DeoptimizeIf(ne, instr, reg, Operand(at));
5143 DeoptimizeIf(ne, instr, reg, Operand(object));
5148 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
5155 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt);
5159 DeoptimizeIf(eq, instr, at, Operand(zero_reg));
5163 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
5166 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object)
5167 : LDeferredCode(codegen), instr_(instr), object_(object) {
5174 virtual LInstruction* instr() OVERRIDE { return instr_; }
5181 if (instr->hydrogen()->IsStabilityCheck()) {
5182 const UniqueSet<Map>* maps = instr->hydrogen()->maps();
5190 LOperand* input = instr->value();
5196 if (instr->hydrogen()->HasMigrationTarget()) {
5197 deferred = new(zone()) DeferredCheckMaps(this, instr, reg);
5201 const UniqueSet<Map>* maps = instr->hydrogen()->maps();
5209 if (instr->hydrogen()->HasMigrationTarget()) {
5212 DeoptimizeIf(ne, instr, map_reg, Operand(map));
5219 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
5220 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped());
5221 Register result_reg = ToRegister(instr->result());
5222 DoubleRegister temp_reg = ToDoubleRegister(instr->temp());
5227 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
5228 Register unclamped_reg = ToRegister(instr->unclamped());
5229 Register result_reg = ToRegister(instr->result());
5234 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
5236 Register input_reg = ToRegister(instr->unclamped());
5237 Register result_reg = ToRegister(instr->result());
5238 DoubleRegister temp_reg = ToDoubleRegister(instr->temp());
5250 DeoptimizeIf(ne, instr, input_reg, Operand(factory()->undefined_value()));
5268 void LCodeGen::DoDoubleBits(LDoubleBits* instr) {
5269 DoubleRegister value_reg = ToDoubleRegister(instr->value());
5270 Register result_reg = ToRegister(instr->result());
5271 if (instr->hydrogen()->bits() == HDoubleBits::HIGH) {
5279 void LCodeGen::DoConstructDouble(LConstructDouble* instr) {
5280 Register hi_reg = ToRegister(instr->hi());
5281 Register lo_reg = ToRegister(instr->lo());
5282 DoubleRegister result_reg = ToDoubleRegister(instr->result());
5287 void LCodeGen::DoAllocate(LAllocate* instr) {
5290 DeferredAllocate(LCodeGen* codegen, LAllocate* instr)
5291 : LDeferredCode(codegen), instr_(instr) { }
5295 virtual LInstruction* instr() OVERRIDE { return instr_; }
5301 new(zone()) DeferredAllocate(this, instr);
5303 Register result = ToRegister(instr->result());
5304 Register scratch = ToRegister(instr->temp1());
5305 Register scratch2 = ToRegister(instr->temp2());
5309 if (instr->hydrogen()->MustAllocateDoubleAligned()) {
5312 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5313 DCHECK(!instr->hydrogen()->IsOldDataSpaceAllocation());
5314 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
5316 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5317 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
5320 if (instr->size()->IsConstantOperand()) {
5321 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5328 Register size = ToRegister(instr->size());
5334 if (instr->hydrogen()->MustPrefillWithFiller()) {
5336 if (instr->size()->IsConstantOperand()) {
5337 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5340 __ Subu(scratch, ToRegister(instr->size()), Operand(kHeapObjectTag));
5353 void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
5354 Register result = ToRegister(instr->result());
5362 if (instr->size()->IsRegister()) {
5363 Register size = ToRegister(instr->size());
5368 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5379 instr->hydrogen()->MustAllocateDoubleAligned());
5380 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5381 DCHECK(!instr->hydrogen()->IsOldDataSpaceAllocation());
5382 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
5384 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5385 DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
5393 Runtime::kAllocateInTargetSpace, 2, instr, instr->context());
5398 void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
5399 DCHECK(ToRegister(instr->value()).is(a0));
5400 DCHECK(ToRegister(instr->result()).is(v0));
5402 CallRuntime(Runtime::kToFastProperties, 1, instr);
5406 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
5407 DCHECK(ToRegister(instr->context()).is(cp));
5415 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
5416 __ li(t3, instr->hydrogen()->literals());
5423 __ li(t2, Operand(Smi::FromInt(instr->hydrogen()->literal_index())));
5424 __ li(t1, Operand(instr->hydrogen()->pattern()));
5425 __ li(t0, Operand(instr->hydrogen()->flags()));
5427 CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr);
5440 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr);
5459 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
5460 DCHECK(ToRegister(instr->context()).is(cp));
5463 bool pretenure = instr->hydrogen()->pretenure();
5464 if (!pretenure && instr->hydrogen()->has_no_literals()) {
5465 FastNewClosureStub stub(isolate(), instr->hydrogen()->strict_mode(),
5466 instr->hydrogen()->kind());
5467 __ li(a2, Operand(instr->hydrogen()->shared_info()));
5468 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
5470 __ li(a2, Operand(instr->hydrogen()->shared_info()));
5474 CallRuntime(Runtime::kNewClosure, 3, instr);
5479 void LCodeGen::DoTypeof(LTypeof* instr) {
5480 DCHECK(ToRegister(instr->result()).is(v0));
5481 Register input = ToRegister(instr->value());
5483 CallRuntime(Runtime::kTypeof, 1, instr);
5487 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
5488 Register input = ToRegister(instr->value());
5493 Condition final_branch_condition = EmitTypeofIs(instr->TrueLabel(chunk_),
5494 instr->FalseLabel(chunk_),
5496 instr->type_literal(),
5504 EmitBranch(instr, final_branch_condition, cmp1, cmp2);
5608 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
5609 Register temp1 = ToRegister(instr->temp());
5613 EmitBranch(instr, eq, temp1,
5654 void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
5656 DCHECK(instr->HasEnvironment());
5657 LEnvironment* env = instr->environment();
5663 void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
5664 Deoptimizer::BailoutType type = instr->hydrogen()->type();
5673 DeoptimizeIf(al, instr, type, zero_reg, Operand(zero_reg),
5674 instr->hydrogen()->reason());
5678 void LCodeGen::DoDummy(LDummy* instr) {
5683 void LCodeGen::DoDummyUse(LDummyUse* instr) {
5688 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
5690 LoadContextFromDeferred(instr->context());
5693 instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
5694 DCHECK(instr->HasEnvironment());
5695 LEnvironment* env = instr->environment();
5700 void LCodeGen::DoStackCheck(LStackCheck* instr) {
5703 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
5704 : LDeferredCode(codegen), instr_(instr) { }
5708 virtual LInstruction* instr() OVERRIDE { return instr_; }
5713 DCHECK(instr->HasEnvironment());
5714 LEnvironment* env = instr->environment();
5717 if (instr->hydrogen()->is_function_entry()) {
5722 DCHECK(instr->context()->IsRegister());
5723 DCHECK(ToRegister(instr->context()).is(cp));
5726 instr);
5729 DCHECK(instr->hydrogen()->is_backwards_branch());
5732 new(zone()) DeferredStackCheck(this, instr);
5736 __ bind(instr->done_label());
5737 deferred_stack_check->SetExit(instr->done_label());
5746 void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
5750 LEnvironment* environment = instr->environment();
5761 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
5762 Register result = ToRegister(instr->result());
5763 Register object = ToRegister(instr->object());
5765 DeoptimizeIf(eq, instr, object, Operand(at));
5769 DeoptimizeIf(eq, instr, object, Operand(null_value));
5772 DeoptimizeIf(eq, instr, at, Operand(zero_reg));
5776 DeoptimizeIf(le, instr, a1, Operand(LAST_JS_PROXY_TYPE));
5788 CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr);
5793 DeoptimizeIf(ne, instr, a1, Operand(at));
5798 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) {
5799 Register map = ToRegister(instr->map());
5800 Register result = ToRegister(instr->result());
5812 FieldMemOperand(result, FixedArray::SizeFor(instr->idx())));
5813 DeoptimizeIf(eq, instr, result, Operand(zero_reg));
5819 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
5820 Register object = ToRegister(instr->value());
5821 Register map = ToRegister(instr->map());
5823 DeoptimizeIf(ne, instr, map, Operand(scratch0()));
5827 void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
5836 instr->pointer_map(), 2, Safepoint::kNoLazyDeopt);
5841 void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
5845 LLoadFieldByIndex* instr,
5850 instr_(instr),
5858 virtual LInstruction* instr() OVERRIDE { return instr_; }
5866 Register object = ToRegister(instr->object());
5867 Register index = ToRegister(instr->index());
5868 Register result = ToRegister(instr->result());
5873 this, instr, result, object, index);
5901 void LCodeGen::DoStoreFrameContext(LStoreFrameContext* instr) {
5902 Register context = ToRegister(instr->context());
5907 void LCodeGen::DoAllocateBlockContext(LAllocateBlockContext* instr) {
5908 Handle<ScopeInfo> scope_info = instr->scope_info();
5910 __ Push(at, ToRegister(instr->function()));
5911 CallRuntime(Runtime::kPushBlockContext, 2, instr);