Home | History | Annotate | Download | only in mips

Lines Matching refs:instr

256     LInstruction* instr = instructions_->at(current_instruction_);
259 if (instr->IsLabel()) {
260 emit_instructions = !LLabel::cast(instr)->HasReplacement();
264 if (FLAG_code_comments && instr->HasInterestingComment(this)) {
267 instr->hydrogen_value()->id(),
268 instr->Mnemonic());
271 RecordAndUpdatePosition(instr->position());
273 instr->CompileToNative(this);
293 code->instr()->hydrogen_value()->id(),
294 code->instr()->Mnemonic());
689 LInstruction* instr) {
690 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT);
696 LInstruction* instr,
699 ASSERT(instr != NULL);
700 LPointerMap* pointers = instr->pointer_map();
703 RecordSafepointWithLazyDeopt(instr, safepoint_mode);
709 LInstruction* instr) {
710 ASSERT(instr != NULL);
711 LPointerMap* pointers = instr->pointer_map();
716 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
722 LInstruction* instr) {
725 instr->pointer_map(), argc, Safepoint::kNoLazyDeopt);
918 LInstruction* instr, SafepointMode safepoint_mode) {
920 RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt);
924 instr->pointer_map(), 0, Safepoint::kLazyDeopt);
1032 void LCodeGen::DoInstructionGap(LInstructionGap* instr) {
1033 DoGap(instr);
1037 void LCodeGen::DoParameter(LParameter* instr) {
1042 void LCodeGen::DoCallStub(LCallStub* instr) {
1043 ASSERT(ToRegister(instr->result()).is(v0));
1044 switch (instr->hydrogen()->major_key()) {
1047 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1052 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1057 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1062 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1067 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1072 TranscendentalCacheStub stub(instr->transcendental_type(),
1074 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1083 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
1089 void LCodeGen::DoModI(LModI* instr) {
1090 HMod* hmod = instr->hydrogen();
1094 const Register left_reg = ToRegister(instr->left());
1095 const Register result_reg = ToRegister(instr->result());
1107 DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg));
1118 const Register left_reg = ToRegister(instr->left());
1119 const Register result_reg = ToRegister(instr->result());
1120 const Register right_reg = ToRegister(instr->right());
1126 DeoptimizeIf(ne, instr->environment(), right_reg, Operand(divisor));
1135 DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg));
1147 const Register left_reg = ToRegister(instr->left());
1148 const Register result_reg = ToRegister(instr->result());
1151 Register right_reg = EmitLoadRegister(instr->right(), scratch);
1158 DeoptimizeIf(eq, instr->environment(), right_reg, Operand(zero_reg));
1167 DeoptimizeIf(eq, instr->environment(), right_reg, Operand(-1));
1176 DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg));
1285 void LCodeGen::DoDivI(LDivI* instr) {
1286 const Register left = ToRegister(instr->left());
1287 const Register right = ToRegister(instr->right());
1288 const Register result = ToRegister(instr->result());
1295 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
1296 DeoptimizeIf(eq, instr->environment(), right, Operand(zero_reg));
1300 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1303 DeoptimizeIf(lt, instr->environment(), right, Operand(zero_reg));
1308 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1311 DeoptimizeIf(eq, instr->environment(), right, Operand(-1));
1315 if (!instr->hydrogen()->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
1317 DeoptimizeIf(ne, instr->environment(), result, Operand(zero_reg));
1323 void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) {
1324 DoubleRegister addend = ToDoubleRegister(instr->addend());
1325 DoubleRegister multiplier = ToDoubleRegister(instr->multiplier());
1326 DoubleRegister multiplicand = ToDoubleRegister(instr->multiplicand());
1329 ASSERT(addend.is(ToDoubleRegister(instr->result())));
1335 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
1336 const Register result = ToRegister(instr->result());
1337 const Register left = ToRegister(instr->left());
1338 const Register remainder = ToRegister(instr->temp());
1341 if (instr->right()->IsConstantOperand()) {
1343 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right()));
1345 DeoptimizeIf(eq, instr->environment(), left, Operand(zero_reg));
1352 instr->environment());
1361 const Register right = ToRegister(instr->right());
1368 DeoptimizeIf(eq, instr->environment(), right, Operand(zero_reg));
1371 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1374 DeoptimizeIf(lt, instr->environment(), right, Operand(zero_reg));
1379 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1382 DeoptimizeIf(eq, instr->environment(), right, Operand(-1));
1399 void LCodeGen::DoMulI(LMulI* instr) {
1401 Register result = ToRegister(instr->result());
1403 Register left = ToRegister(instr->left());
1404 LOperand* right_op = instr->right();
1406 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1408 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
1414 instr->hydrogen()->right()->representation());
1419 DeoptimizeIf(eq, instr->environment(), left, Operand(zero_reg));
1430 DeoptimizeIf(lt, instr->environment(), left, Operand(zero_reg));
1476 __ Or(ToRegister(instr->temp()), left, right);
1481 if (instr->hydrogen()->representation().IsSmi()) {
1492 DeoptimizeIf(ne, instr->environment(), scratch, Operand(at));
1494 if (instr->hydrogen()->representation().IsSmi()) {
1507 instr->environment(),
1508 ToRegister(instr->temp()),
1516 void LCodeGen::DoBitI(LBitI* instr) {
1517 LOperand* left_op = instr->left();
1518 LOperand* right_op = instr->right();
1521 Register result = ToRegister(instr->result());
1531 switch (instr->op()) {
1552 void LCodeGen::DoShiftI(LShiftI* instr) {
1555 LOperand* right_op = instr->right();
1556 Register left = ToRegister(instr->left());
1557 Register result = ToRegister(instr->result());
1563 switch (instr->op()) {
1572 if (instr->can_deopt()) {
1573 DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg));
1587 switch (instr->op()) {
1606 if (instr->can_deopt()) {
1608 DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg));
1615 if (instr->hydrogen_value()->representation().IsSmi() &&
1616 instr->can_deopt()) {
1623 DeoptimizeIf(lt, instr->environment(), scratch, Operand(zero_reg));
1639 void LCodeGen::DoSubI(LSubI* instr) {
1640 LOperand* left = instr->left();
1641 LOperand* right = instr->right();
1642 LOperand* result = instr->result();
1643 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1673 DeoptimizeIf(lt, instr->environment(), overflow, Operand(zero_reg));
1678 void LCodeGen::DoConstantI(LConstantI* instr) {
1679 __ li(ToRegister(instr->result()), Operand(instr->value()));
1683 void LCodeGen::DoConstantS(LConstantS* instr) {
1684 __ li(ToRegister(instr->result()), Operand(instr->value()));
1688 void LCodeGen::DoConstantD(LConstantD* instr) {
1689 ASSERT(instr->result()->IsDoubleRegister());
1690 DoubleRegister result = ToDoubleRegister(instr->result());
1691 double v = instr->value();
1696 void LCodeGen::DoConstantE(LConstantE* instr) {
1697 __ li(ToRegister(instr->result()), Operand(instr->value()));
1701 void LCodeGen::DoConstantT(LConstantT* instr) {
1702 Handle<Object> value = instr->value();
1704 __ LoadObject(ToRegister(instr->result()), value);
1708 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1709 Register result = ToRegister(instr->result());
1710 Register map = ToRegister(instr->value());
1715 void LCodeGen::DoElementsKind(LElementsKind* instr) {
1716 Register result = ToRegister(instr->result());
1717 Register input = ToRegister(instr->value());
1729 void LCodeGen::DoValueOf(LValueOf* instr) {
1730 Register input = ToRegister(instr->value());
1731 Register result = ToRegister(instr->result());
1732 Register map = ToRegister(instr->temp());
1735 if (!instr->hydrogen()->value()->IsHeapObject()) {
1750 void LCodeGen::DoDateField(LDateField* instr) {
1751 Register object = ToRegister(instr->date());
1752 Register result = ToRegister(instr->result());
1753 Register scratch = ToRegister(instr->temp());
1754 Smi* index = instr->index();
1762 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
1764 DeoptimizeIf(ne, instr->environment(), scratch, Operand(JS_DATE_TYPE));
1788 void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
1789 Register string = ToRegister(instr->string());
1790 Register index = ToRegister(instr->index());
1791 Register value = ToRegister(instr->value());
1793 String::Encoding encoding = instr->encoding();
1821 void LCodeGen::DoThrow(LThrow* instr) {
1822 Register input_reg = EmitLoadRegister(instr->value(), at);
1824 CallRuntime(Runtime::kThrow, 1, instr);
1832 void LCodeGen::DoAddI(LAddI* instr) {
1833 LOperand* left = instr->left();
1834 LOperand* right = instr->right();
1835 LOperand* result = instr->result();
1836 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1866 DeoptimizeIf(lt, instr->environment(), overflow, Operand(zero_reg));
1871 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
1872 LOperand* left = instr->left();
1873 LOperand* right = instr->right();
1874 HMathMinMax::Operation operation = instr->hydrogen()->operation();
1876 if (instr->hydrogen()->representation().IsSmiOrInteger32()) {
1881 Register result_reg = ToRegister(instr->result());
1893 ASSERT(instr->hydrogen()->representation().IsDouble());
1896 FPURegister result_reg = ToDoubleRegister(instr->result());
1933 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1934 DoubleRegister left = ToDoubleRegister(instr->left());
1935 instr->right());
1936 DoubleRegister result = ToDoubleRegister(instr->result());
1937 switch (instr->op()) {
1974 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
1975 ASSERT(ToRegister(instr->left()).is(a1));
1976 ASSERT(ToRegister(instr->right()).is(a0));
1977 ASSERT(ToRegister(instr->result()).is(v0));
1979 BinaryOpStub stub(instr->op(), NO_OVERWRITE);
1980 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1995 void LCodeGen::EmitBranch(InstrType instr,
1999 int left_block = instr->TrueDestination(chunk_);
2000 int right_block = instr->FalseDestination(chunk_);
2018 void LCodeGen::EmitBranchF(InstrType instr,
2022 int right_block = instr->FalseDestination(chunk_);
2023 int left_block = instr->TrueDestination(chunk_);
2043 void LCodeGen::EmitFalseBranchF(InstrType instr,
2047 int false_block = instr->FalseDestination(chunk_);
2053 void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
2058 void LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) {
2059 Representation r = instr->hydrogen()->value()->representation();
2061 EmitBranch(instr, al, zero_reg, Operand(zero_reg));
2064 Register reg = ToRegister(instr->value());
2065 HType type = instr->hydrogen()->value()->type();
2067 EmitBranch(instr, al, zero_reg, Operand(zero_reg));
2069 __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
2072 EmitBranch(instr, eq, scratch0(), Operand(at));
2077 void LCodeGen::DoBranch(LBranch* instr) {
2078 Representation r = instr->hydrogen()->value()->representation();
2081 Register reg = ToRegister(instr->value());
2082 EmitBranch(instr, ne, reg, Operand(zero_reg));
2085 DoubleRegister reg = ToDoubleRegister(instr->value());
2087 EmitBranchF(instr, nue, reg, kDoubleRegZero);
2090 Register reg = ToRegister(instr->value());
2091 HType type = instr->hydrogen()->value()->type();
2095 EmitBranch(instr, eq, reg, Operand(at));
2098 EmitBranch(instr, ne, reg, Operand(zero_reg));
2101 EmitBranch(instr, al, zero_reg, Operand(zero_reg));
2107 EmitBranchF(instr, nue, dbl_scratch, kDoubleRegZero);
2111 EmitBranch(instr, ne, at, Operand(zero_reg));
2113 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
2120 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at));
2125 __ Branch(instr->TrueLabel(chunk_), eq, reg, Operand(at));
2127 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at));
2132 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at));
2137 __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(zero_reg));
2138 __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
2142 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
2152 __ Branch(instr->FalseLabel(chunk_), ne, at, Operand(zero_reg));
2159 __ Branch(instr->TrueLabel(chunk_),
2169 __ Branch(instr->TrueLabel(chunk_), ne, at, Operand(zero_reg));
2170 __ Branch(instr->FalseLabel(chunk_));
2178 __ Branch(instr->TrueLabel(chunk_), eq, scratch, Operand(SYMBOL_TYPE));
2188 __ BranchF(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
2191 __ Branch(instr->FalseLabel(chunk_));
2198 DeoptimizeIf(al, instr->environment(), zero_reg, Operand(zero_reg));
2212 void LCodeGen::DoGoto(LGoto* instr) {
2213 EmitGoto(instr->block_id());
2245 void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) {
2246 LOperand* left = instr->left();
2247 LOperand* right = instr->right();
2248 Condition cond = TokenToCondition(instr->op(), false);
2254 int next_block = EvalComparison(instr->op(), left_val, right_val) ?
2255 instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_);
2258 if (instr->is_double()) {
2266 __ BranchF(NULL, instr->FalseLabel(chunk_), eq,
2269 EmitBranchF(instr, cond, left_reg, right_reg);
2276 if (instr->hydrogen_value()->representation().IsSmi()) {
2285 if (instr->hydrogen_value()->representation().IsSmi()) {
2299 EmitBranch(instr, cond, cmp_left, cmp_right);
2305 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
2306 Register left = ToRegister(instr->left());
2307 Register right = ToRegister(instr->right());
2309 EmitBranch(instr, eq, left, Operand(right));
2313 void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
2314 if (instr->hydrogen()->representation().IsTagged()) {
2315 Register input_reg = ToRegister(instr->object());
2317 EmitBranch(instr, eq, input_reg, Operand(at));
2321 DoubleRegister input_reg = ToDoubleRegister(instr->object());
2322 EmitFalseBranchF(instr, eq, input_reg, input_reg);
2326 EmitBranch(instr, eq, scratch, Operand(kHoleNanUpper32));
2356 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
2357 Register reg = ToRegister(instr->value());
2358 Register temp1 = ToRegister(instr->temp());
2363 instr->FalseLabel(chunk_), instr->TrueLabel(chunk_));
2365 EmitBranch(instr, true_cond, temp2,
2383 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
2384 Register reg = ToRegister(instr->value());
2385 Register temp1 = ToRegister(instr->temp());
2388 instr->hydrogen()->value()->IsHeapObject()
2391 EmitIsString(reg, temp1, instr->FalseLabel(chunk_), check_needed);
2393 EmitBranch(instr, true_cond, temp1,
2398 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
2399 Register input_reg = EmitLoadRegister(instr->value(), at);
2401 EmitBranch(instr, eq, at, Operand(zero_reg));
2405 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
2406 Register input = ToRegister(instr->value());
2407 instr->temp());
2409 if (!instr->hydrogen()->value()->IsHeapObject()) {
2410 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2415 EmitBranch(instr, ne, at, Operand(zero_reg));
2439 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
2440 Token::Value op = instr->op();
2443 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2447 EmitBranch(instr, condition, v0, Operand(zero_reg));
2451 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
2452 InstanceType from = instr->from();
2453 InstanceType to = instr->to();
2460 static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
2461 InstanceType from = instr->from();
2462 InstanceType to = instr->to();
2471 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
2473 Register input = ToRegister(instr->value());
2475 if (!instr->hydrogen()->value()->IsHeapObject()) {
2476 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2480 EmitBranch(instr,
2481 BranchCondition(instr->hydrogen()),
2483 Operand(TestType(instr->hydrogen())));
2487 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
2488 Register input = ToRegister(instr->value());
2489 Register result = ToRegister(instr->result());
2499 LHasCachedArrayIndexAndBranch* instr) {
2500 Register input = ToRegister(instr->value());
2506 EmitBranch(instr, eq, at, Operand(zero_reg));
2576 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2577 Register input = ToRegister(instr->value());
2579 Register temp2 = ToRegister(instr->temp());
2580 Handle<String> class_name = instr->hydrogen()->class_name();
2582 EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
2585 EmitBranch(instr, eq, temp, Operand(class_name));
2589 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
2590 Register reg = ToRegister(instr->value());
2591 Register temp = ToRegister(instr->temp());
2594 EmitBranch(instr, eq, temp, Operand(instr->map()));
2598 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
2600 ASSERT(ToRegister(instr->left()).is(a0)); // Object is in a0.
2601 ASSERT(ToRegister(instr->right()).is(a1)); // Function is in a1.
2602 Register result = ToRegister(instr->result());
2606 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
2617 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
2621 LInstanceOfKnownGlobal* instr)
2622 : LDeferredCode(codegen), instr_(instr) { }
2626 virtual LInstruction* instr() { return instr_; }
2635 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
2638 Register object = ToRegister(instr->value());
2639 Register temp = ToRegister(instr->temp());
2640 Register result = ToRegister(instr->result());
2694 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
2696 Register result = ToRegister(instr->result());
2713 Register temp = ToRegister(instr->temp());
2715 __ LoadHeapObject(InstanceofStub::right(), instr->function());
2727 instr,
2729 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment();
2737 void LCodeGen::DoInstanceSize(LInstanceSize* instr) {
2738 Register object = ToRegister(instr->object());
2739 Register result = ToRegister(instr->result());
2745 void LCodeGen::DoCmpT(LCmpT* instr) {
2746 Token::Value op = instr->op();
2749 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2759 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex);
2761 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
2766 void LCodeGen::DoReturn(LReturn* instr) {
2791 if (instr->has_constant_parameter_count()) {
2792 int parameter_count = ToInteger32(instr->constant_parameter_count());
2798 Register reg = ToRegister(instr->parameter_count());
2813 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
2814 Register result = ToRegister(instr->result());
2815 __ li(at, Operand(Handle<Object>(instr->hydrogen()->cell())));
2817 if (instr->hydrogen()->RequiresHoleCheck()) {
2819 DeoptimizeIf(eq, instr->environment(), result, Operand(at));
2824 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
2825 ASSERT(ToRegister(instr->global_object()).is(a0));
2826 ASSERT(ToRegister(instr->result()).is(v0));
2828 __ li(a2, Operand(instr->name()));
2829 RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET
2832 CallCode(ic, mode, instr);
2836 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
2837 Register value = ToRegister(instr->value());
2841 __ li(cell, Operand(instr->hydrogen()->cell()));
2847 if (instr->hydrogen()->RequiresHoleCheck()) {
2849 Register payload = ToRegister(instr->temp());
2852 DeoptimizeIf(eq, instr->environment(), payload, Operand(at));
2861 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) {
2862 ASSERT(ToRegister(instr->global_object()).is(a1));
2863 ASSERT(ToRegister(instr->value()).is(a0));
2865 __ li(a2, Operand(instr->name()));
2866 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
2869 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr);
2873 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
2874 Register context = ToRegister(instr->context());
2875 Register result = ToRegister(instr->result());
2877 __ lw(result, ContextOperand(context, instr->slot_index()));
2878 if (instr->hydrogen()->RequiresHoleCheck()) {
2881 if (instr->hydrogen()->DeoptimizesOnHole()) {
2882 DeoptimizeIf(eq, instr->environment(), result, Operand(at));
2893 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
2894 Register context = ToRegister(instr->context());
2895 Register value = ToRegister(instr->value());
2897 MemOperand target = ContextOperand(context, instr->slot_index());
2901 if (instr->hydrogen()->RequiresHoleCheck()) {
2905 if (instr->hydrogen()->DeoptimizesOnHole()) {
2906 DeoptimizeIf(eq, instr->environment(), scratch, Operand(at));
2913 if (instr->hydrogen()->NeedsWriteBarrier()) {
2915 instr->hydrogen()->value()->IsHeapObject()
2931 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
2932 HObjectAccess access = instr->hydrogen()->access();
2934 Register object = ToRegister(instr->object());
2937 Register result = ToRegister(instr->result());
2942 if (instr->hydrogen()->representation().IsDouble()) {
2943 DoubleRegister result = ToDoubleRegister(instr->result());
2948 Register result = ToRegister(instr->result());
2958 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
2959 ASSERT(ToRegister(instr->object()).is(a0));
2960 ASSERT(ToRegister(instr->result()).is(v0));
2963 __ li(a2, Operand(instr->name()));
2965 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2969 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
2971 Register function = ToRegister(instr->function());
2972 Register result = ToRegister(instr->result());
2977 DeoptimizeIf(ne, instr->environment(), scratch, Operand(JS_FUNCTION_TYPE));
2991 DeoptimizeIf(eq, instr->environment(), result, Operand(at));
3013 LLoadExternalArrayPointer* instr) {
3014 Register to_reg = ToRegister(instr->result());
3015 Register from_reg = ToRegister(instr->object());
3021 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
3022 Register arguments = ToRegister(instr->arguments());
3023 Register result = ToRegister(instr->result());
3024 if (instr->length()->IsConstantOperand() &&
3025 instr->index()->IsConstantOperand()) {
3026 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3027 int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
3031 Register length = ToRegister(instr->length());
3032 Register index = ToRegister(instr->index());
3044 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
3045 Register external_pointer = ToRegister(instr->elements());
3047 ElementsKind elements_kind = instr->elements_kind();
3048 bool key_is_constant = instr->key()->IsConstantOperand();
3051 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
3056 key = ToRegister(instr->key());
3059 int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
3061 int additional_offset = instr->additional_index() << element_size_shift;
3065 FPURegister result = ToDoubleRegister(instr->result());
3079 Register result = ToRegister(instr->result());
3083 instr->additional_index(), additional_offset);
3103 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
3104 DeoptimizeIf(Ugreater_equal, instr->environment(),
3125 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
3126 Register elements = ToRegister(instr->elements());
3127 bool key_is_constant = instr->key()->IsConstantOperand();
3129 DoubleRegister result = ToDoubleRegister(instr->result());
3133 int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
3137 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
3142 key = ToRegister(instr->key());
3146 ((constant_key + instr->additional_index()) << element_size_shift);
3153 if (instr->hydrogen()->RequiresHoleCheck()) {
3155 DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32));
3160 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3161 Register elements = ToRegister(instr->elements());
3162 Register result = ToRegister(instr->result());
3167 if (instr->key()->IsConstantOperand()) {
3168 LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
3170 instr->additional_index());
3173 Register key = EmitLoadRegister(instr->key(), scratch0());
3178 if (instr->hydrogen()->key()->representation().IsSmi()) {
3185 offset = FixedArray::OffsetOfElementAt(instr->additional_index());
3190 if (instr->hydrogen()->RequiresHoleCheck()) {
3191 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
3193 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg));
3196 DeoptimizeIf(eq, instr->environment(), result, Operand(scratch));
3202 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
3203 if (instr->is_external()) {
3204 DoLoadKeyedExternalArray(instr);
3205 } else if (instr->hydrogen()->representation().IsDouble()) {
3206 DoLoadKeyedFixedDoubleArray(instr);
3208 DoLoadKeyedFixedArray(instr);
3257 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
3258 ASSERT(ToRegister(instr->object()).is(a1));
3259 ASSERT(ToRegister(instr->key()).is(a0));
3262 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3266 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
3269 Register result = ToRegister(instr->result());
3271 if (instr->hydrogen()->from_inlined()) {
3288 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
3289 Register elem = ToRegister(instr->elements());
3290 Register result = ToRegister(instr->result());
3309 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
3310 Register receiver = ToRegister(instr->receiver());
3311 Register function = ToRegister(instr->function());
3341 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg));
3344 DeoptimizeIf(lt, instr->environment(),
3356 void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
3357 Register receiver = ToRegister(instr->receiver());
3358 Register function = ToRegister(instr->function());
3359 Register length = ToRegister(instr->length());
3360 Register elements = ToRegister(instr->elements());
3364 ASSERT(ToRegister(instr->result()).is(v0));
3369 DeoptimizeIf(hi, instr->environment(), length, Operand(kArgumentsLimit));
3393 ASSERT(instr->HasPointerMap());
3394 LPointerMap* pointers = instr->pointer_map();
3407 void LCodeGen::DoPushArgument(LPushArgument* instr) {
3408 LOperand* argument = instr->value();
3418 void LCodeGen::DoDrop(LDrop* instr) {
3419 __ Drop(instr->count());
3423 void LCodeGen::DoThisFunction(LThisFunction* instr) {
3424 Register result = ToRegister(instr->result());
3429 void LCodeGen::DoContext(LContext* instr) {
3431 Register result = ToRegister(instr->result());
3432 for (HUseIterator it(instr->hydrogen()->uses()); !it.Done(); it.Advance()) {
3441 void LCodeGen::DoOuterContext(LOuterContext* instr) {
3442 Register context = ToRegister(instr->context());
3443 Register result = ToRegister(instr->result());
3449 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
3450 __ LoadHeapObject(scratch0(), instr->hydrogen()->pairs());
3451 __ li(scratch1(), Operand(Smi::FromInt(instr->hydrogen()->flags())));
3454 CallRuntime(Runtime::kDeclareGlobals, 3, instr);
3458 void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
3459 Register result = ToRegister(instr->result());
3464 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
3465 Register global = ToRegister(instr->global_object());
3466 Register result = ToRegister(instr->result());
3474 LInstruction* instr,
3482 LPointerMap* pointers = instr->pointer_map();
3505 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
3519 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
3520 ASSERT(ToRegister(instr->result()).is(v0));
3522 CallKnownFunction(instr->hydrogen()->function(),
3523 instr->hydrogen()->formal_parameter_count(),
3524 instr->arity(),
3525 instr,
3531 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3532 Register input = ToRegister(instr->value());
3533 Register result = ToRegister(instr->result());
3539 DeoptimizeIf(ne, instr->environment(), scratch, Operand(at));
3573 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
3596 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
3597 Register input = ToRegister(instr->value());
3598 Register result = ToRegister(instr->result());
3605 DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg));
3610 void LCodeGen::DoMathAbs(LMathAbs* instr) {
3614 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr)
3615 : LDeferredCode(codegen), instr_(instr) { }
3619 virtual LInstruction* instr() { return instr_; }
3624 Representation r = instr->hydrogen()->value()->representation();
3626 FPURegister input = ToDoubleRegister(instr->value());
3627 FPURegister result = ToDoubleRegister(instr->result());
3630 EmitIntegerMathAbs(instr);
3634 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
3635 Register input = ToRegister(instr->value());
3639 EmitIntegerMathAbs(instr);
3645 void LCodeGen::DoMathFloor(LMathFloor* instr) {
3646 DoubleRegister input = ToDoubleRegister(instr->value());
3647 Register result = ToRegister(instr->result());
3649 Register except_flag = ToRegister(instr->temp());
3659 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg));
3661 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3667 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg));
3673 void LCodeGen::DoMathRound(LMathRound* instr) {
3674 DoubleRegister input = ToDoubleRegister(instr->value());
3675 Register result = ToRegister(instr->result());
3676 DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp());
3691 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3700 DeoptimizeIf(ge, instr->environment(), scratch,
3713 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3715 DeoptimizeIf(lt, instr->environment(), result,
3735 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg));
3737 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3743 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg));
3749 void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
3750 DoubleRegister input = ToDoubleRegister(instr->value());
3751 DoubleRegister result = ToDoubleRegister(instr->result());
3756 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
3757 DoubleRegister input = ToDoubleRegister(instr->value());
3758 DoubleRegister result = ToDoubleRegister(instr->result());
3759 DoubleRegister temp = ToDoubleRegister(instr->temp());
3780 void LCodeGen::DoPower(LPower* instr) {
3781 Representation exponent_type = instr->hydrogen()->right()->representation();
3784 ASSERT(!instr->right()->IsDoubleRegister() ||
3785 ToDoubleRegister(instr->right()).is(f4));
3786 ASSERT(!instr->right()->IsRegister() ||
3787 ToRegister(instr->right()).is(a2));
3788 ASSERT(ToDoubleRegister(instr->left()).is(f2));
3789 ASSERT(ToDoubleRegister(instr->result()).is(f0));
3798 DeoptimizeIf(ne, instr->environment(), t3, Operand(at));
3813 void LCodeGen::DoRandom(LRandom* instr) {
3816 DeferredDoRandom(LCodeGen* codegen, LRandom* instr)
3817 : LDeferredCode(codegen), instr_(instr) { }
3819 virtual LInstruction* instr() { return instr_; }
3824 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr);
3827 ASSERT(ToDoubleRegister(instr->result()).is(f0));
3828 ASSERT(ToRegister(instr->global_object()).is(a0));
3883 void LCodeGen::DoDeferredRandom(LRandom* instr) {
3890 void LCodeGen::DoMathExp(LMathExp* instr) {
3891 DoubleRegister input = ToDoubleRegister(instr->value());
3892 DoubleRegister result = ToDoubleRegister(instr->result());
3893 DoubleRegister double_scratch1 = ToDoubleRegister(instr->double_temp());
3895 Register temp1 = ToRegister(instr->temp1());
3896 Register temp2 = ToRegister(instr->temp2());
3904 void LCodeGen::DoMathLog(LMathLog* instr) {
3905 ASSERT(ToDoubleRegister(instr->result()).is(f4));
3908 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3912 void LCodeGen::DoMathTan(LMathTan* instr) {
3913 ASSERT(ToDoubleRegister(instr->result()).is(f4));
3916 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3920 void LCodeGen::DoMathCos(LMathCos* instr) {
3921 ASSERT(ToDoubleRegister(instr->result()).is(f4));
3924 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3928 void LCodeGen::DoMathSin(LMathSin* instr) {
3929 ASSERT(ToDoubleRegister(instr->result()).is(f4));
3932 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3936 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
3937 ASSERT(ToRegister(instr->function()).is(a1));
3938 ASSERT(instr->HasPointerMap());
3940 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
3942 LPointerMap* pointers = instr->pointer_map();
3945 ParameterCount count(instr->arity());
3950 instr->hydrogen()->formal_parameter_count(),
3951 instr->arity(),
3952 instr,
3959 void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
3960 ASSERT(ToRegister(instr->result()).is(v0));
3962 int arity = instr->arity();
3965 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3970 void LCodeGen::DoCallNamed(LCallNamed* instr) {
3971 ASSERT(ToRegister(instr->result()).is(v0));
3973 int arity = instr->arity();
3977 __ li(a2, Operand(instr->name()));
3978 CallCode(ic, mode, instr);
3984 void LCodeGen::DoCallFunction(LCallFunction* instr) {
3985 ASSERT(ToRegister(instr->function()).is(a1));
3986 ASSERT(ToRegister(instr->result()).is(v0));
3988 int arity = instr->arity();
3990 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3995 void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
3996 ASSERT(ToRegister(instr->result()).is(v0));
3998 int arity = instr->arity();
4002 __ li(a2, Operand(instr->name()));
4003 CallCode(ic, mode, instr);
4008 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
4009 ASSERT(ToRegister(instr->result()).is(v0));
4010 CallKnownFunction(instr->hydrogen()->target(),
4011 instr->hydrogen()->formal_parameter_count(),
4012 instr->arity(),
4013 instr,
4019 void LCodeGen::DoCallNew(LCallNew* instr) {
4020 ASSERT(ToRegister(instr->constructor()).is(a1));
4021 ASSERT(ToRegister(instr->result()).is(v0));
4023 __ li(a0, Operand(instr->arity()));
4028 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4032 void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
4033 ASSERT(ToRegister(instr->constructor()).is(a1));
4034 ASSERT(ToRegister(instr->result()).is(v0));
4036 __ li(a0, Operand(instr->arity()));
4037 __ li(a2, Operand(instr->hydrogen()->property_cell()));
4038 ElementsKind kind = instr->hydrogen()->elements_kind();
4045 if (instr->arity() == 0) {
4047 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4048 } else if (instr->arity() == 1) {
4060 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4066 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4070 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4075 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
4076 CallRuntime(instr->function(), instr->arity(), instr);
4080 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
4081 Register result = ToRegister(instr->result());
4082 Register base = ToRegister(instr->base_object());
4083 __ Addu(result, base, Operand(instr->offset()));
4087 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
4088 Representation representation = instr->representation();
4090 Register object = ToRegister(instr->object());
4092 HObjectAccess access = instr->hydrogen()->access();
4096 Register value = ToRegister(instr->value());
4101 Handle<Map> transition = instr->transition();
4104 Register value = ToRegister(instr->value());
4105 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
4107 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg));
4112 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4113 DoubleRegister value = ToDoubleRegister(instr->value());
4121 if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
4122 Register temp = ToRegister(instr->temp());
4136 Register value = ToRegister(instr->value());
4139 instr->hydrogen()->value()->IsHeapObject()
4143 if (instr->hydrogen()->NeedsWriteBarrier()) {
4157 if (instr->hydrogen()->NeedsWriteBarrier()) {
4173 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
4174 ASSERT(ToRegister(instr->object()).is(a1));
4175 ASSERT(ToRegister(instr->value()).is(a0));
4178 __ li(a2, Operand(instr->name()));
4179 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
4182 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4201 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
4202 if (instr->hydrogen()->skip_check()) return;
4204 Condition condition = instr->hydrogen()->allow_equality() ? hi : hs;
4205 if (instr->index()->IsConstantOperand()) {
4207 ToInteger32(LConstantOperand::cast(instr->index()));
4208 if (instr->hydrogen()->length()->representation().IsSmi()) {
4214 instr,
4216 Operand(ToRegister(instr->length())));
4219 instr,
4220 ToRegister(instr->index()),
4221 Operand(ToRegister(instr->length())));
4226 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4227 Register external_pointer = ToRegister(instr->elements());
4229 ElementsKind elements_kind = instr->elements_kind();
4230 bool key_is_constant = instr->key()->IsConstantOperand();
4233 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
4238 key = ToRegister(instr->key());
4241 int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
4243 int additional_offset = instr->additional_index() << element_size_shift;
4247 FPURegister value(ToDoubleRegister(instr->value()));
4263 Register value(ToRegister(instr->value()));
4267 instr->additional_index(), additional_offset);
4299 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
4300 DoubleRegister value = ToDoubleRegister(instr->value());
4301 Register elements = ToRegister(instr->elements());
4304 bool key_is_constant = instr->key()->IsConstantOperand();
4311 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
4316 key = ToRegister(instr->key());
4319 int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
4331 if (instr->NeedsCanonicalization()) {
4343 __ sdc1(value, MemOperand(scratch, instr->additional_index() <<
4348 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4349 Register value = ToRegister(instr->value());
4350 Register elements = ToRegister(instr->elements());
4351 Register key = instr->key()->IsRegister() ? ToRegister(instr->key())
4358 if (instr->key()->IsConstantOperand()) {
4359 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4360 LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
4362 instr->additional_index());
4369 if (instr->hydrogen()->key()->representation().IsSmi()) {
4376 offset = FixedArray::OffsetOfElementAt(instr->additional_index());
4380 if (instr->hydrogen()->NeedsWriteBarrier()) {
4382 instr->hydrogen()->value()->IsHeapObject()
4397 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
4399 if (instr->is_external()) {
4400 DoStoreKeyedExternalArray(instr);
4401 } else if (instr->hydrogen()->value()->representation().IsDouble()) {
4402 DoStoreKeyedFixedDoubleArray(instr);
4404 DoStoreKeyedFixedArray(instr);
4409 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
4410 ASSERT(ToRegister(instr->object()).is(a2));
4411 ASSERT(ToRegister(instr->key()).is(a1));
4412 ASSERT(ToRegister(instr->value()).is(a0));
4414 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
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());
4449 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4455 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
4456 Register object = ToRegister(instr->object());
4457 Register temp = ToRegister(instr->temp());
4460 DeoptimizeIf(al, instr->environment());
4465 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4466 __ push(ToRegister(instr->left()));
4467 __ push(ToRegister(instr->right()));
4468 StringAddStub stub(instr->hydrogen()->flags());
4469 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4473 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
4476 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
4477 : LDeferredCode(codegen), instr_(instr) { }
4479 virtual LInstruction* instr() { return instr_; }
4485 new(zone()) DeferredStringCharCodeAt(this, instr);
4487 ToRegister(instr->string()),
4488 ToRegister(instr->index()),
4489 ToRegister(instr->result()),
4495 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
4496 Register string = ToRegister(instr->string());
4497 Register result = ToRegister(instr->result());
4509 if (instr->index()->IsConstantOperand()) {
4510 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
4514 Register index = ToRegister(instr->index());
4518 CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, instr);
4525 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
4528 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
4529 : LDeferredCode(codegen), instr_(instr) { }
4531 virtual LInstruction* instr() { return instr_; }
4537 new(zone()) DeferredStringCharFromCode(this, instr);
4539 ASSERT(instr->hydrogen()->value()->representation().IsInteger32());
4540 Register char_code = ToRegister(instr->char_code());
4541 Register result = ToRegister(instr->result());
4557 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
4558 Register char_code = ToRegister(instr->char_code());
4559 Register result = ToRegister(instr->result());
4569 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr);
4574 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4575 LOperand* input = instr->value();
4577 LOperand* output = instr->result();
4591 void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) {
4592 LOperand* input = instr->value();
4594 LOperand* output = instr->result();
4599 if (!instr->hydrogen()->value()->HasRange() ||
4600 !instr->hydrogen()->value()->range()->IsInSmiRange()) {
4601 DeoptimizeIf(lt, instr->environment(), scratch, Operand(zero_reg));
4606 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4607 LOperand* input = instr->value();
4608 LOperand* output = instr->result();
4616 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4619 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
4620 : LDeferredCode(codegen), instr_(instr) { }
4626 virtual LInstruction* instr() { 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) { }
4652 virtual LInstruction* instr() { return instr_; }
4657 LOperand* input = instr->value();
4658 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4661 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4668 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
4673 Register dst = ToRegister(instr->result());
4709 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
4722 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
4725 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4726 : LDeferredCode(codegen), instr_(instr) { }
4728 virtual LInstruction* instr() { return instr_; }
4733 DoubleRegister input_reg = ToDoubleRegister(instr->value());
4735 Register reg = ToRegister(instr->result());
4736 Register temp1 = ToRegister(instr->temp());
4737 Register temp2 = ToRegister(instr->temp2());
4739 instr);
4755 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
4759 Register reg = ToRegister(instr->result());
4763 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
4769 void LCodeGen::DoSmiTag(LSmiTag* instr) {
4770 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
4771 __ SmiTag(ToRegister(instr->result()), ToRegister(instr->value()));
4775 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
4777 Register input = ToRegister(instr->value());
4778 Register result = ToRegister(instr->result());
4779 if (instr->needs_check()) {
4784 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg));
4848 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
4849 Register input_reg = ToRegister(instr->value());
4851 Register scratch2 = ToRegister(instr->temp());
4853 DoubleRegister double_scratch2 = ToDoubleRegister(instr->temp3());
4867 if (instr->truncating()) {
4868 Register scratch3 = ToRegister(instr->temp2());
4880 DeoptimizeIf(ne, instr->environment(), input_reg, Operand(at));
4881 ASSERT(ToRegister(instr->result()).is(input_reg));
4896 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(at));
4912 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg));
4914 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
4919 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg));
4926 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
4929 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
4930 : LDeferredCode(codegen), instr_(instr) { }
4932 virtual LInstruction* instr() { return instr_; }
4937 LOperand* input = instr->value();
4939 ASSERT(input->Equals(instr->result()));
4943 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
4954 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
4955 LOperand* input = instr->value();
4957 LOperand* result = instr->result();
4963 HValue* value = instr->hydrogen()->value();
4968 instr->hydrogen()->can_convert_undefined_to_nan(),
4969 instr->hydrogen()->deoptimize_on_minus_zero(),
4970 instr->environment(),
4975 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
4976 Register result_reg = ToRegister(instr->result());
4978 Register scratch2 = ToRegister(instr->temp());
4979 DoubleRegister double_input = ToDoubleRegister(instr->value());
4981 if (instr->truncating()) {
4982 Register scratch3 = ToRegister(instr->temp2());
5002 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg));
5004 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5009 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg));
5016 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
5017 Register result_reg = ToRegister(instr->result());
5019 Register scratch2 = ToRegister(instr->temp());
5020 DoubleRegister double_input = ToDoubleRegister(instr->value());
5022 if (instr->truncating()) {
5023 Register scratch3 = ToRegister(instr->temp2());
5043 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg));
5045 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5050 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg));
5055 DeoptimizeIf(lt, instr->environment(), scratch1, Operand(zero_reg));
5059 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
5060 LOperand* input = instr->value();
5062 DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg));
5066 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
5067 if (!instr->hydrogen()->value()->IsHeapObject()) {
5068 LOperand* input = instr->value();
5070 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
5075 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
5076 Register input = ToRegister(instr->value());
5081 if (instr->hydrogen()->is_interval_check()) {
5084 instr->hydrogen()->GetCheckInterval(&first, &last);
5088 DeoptimizeIf(ne, instr->environment(), scratch, Operand(first));
5090 DeoptimizeIf(lo, instr->environment(), scratch, Operand(first));
5093 DeoptimizeIf(hi, instr->environment(), scratch, Operand(last));
5099 instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
5104 DeoptimizeIf(tag == 0 ? ne : eq, instr->environment(),
5108 DeoptimizeIf(ne, instr->environment(), scratch, Operand(tag));
5114 void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
5115 Register reg = ToRegister(instr->value());
5116 Handle<JSFunction> target = instr->hydrogen()->target();
5119 Register reg = ToRegister(instr->value());
5123 DeoptimizeIf(ne, instr->environment(), reg,
5126 DeoptimizeIf(ne, instr->environment(), reg,
5132 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
5136 CallRuntimeFromDeferred(Runtime::kMigrateInstance, 1, instr);
5140 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
5144 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
5147 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object)
5148 : LDeferredCode(codegen), instr_(instr), object_(object) {
5155 virtual LInstruction* instr() { return instr_; }
5162 if (instr->hydrogen()->CanOmitMapChecks()) return;
5164 LOperand* input = instr->value();
5167 SmallMapList* map_set = instr->hydrogen()->map_set();
5171 if (instr->hydrogen()->has_migration_target()) {
5172 deferred = new(zone()) DeferredCheckMaps(this, instr, reg);
5183 if (instr->hydrogen()->has_migration_target()) {
5186 DeoptimizeIf(ne, instr->environment(), map_reg, Operand(map));
5193 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
5194 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped());
5195 Register result_reg = ToRegister(instr->result());
5196 DoubleRegister temp_reg = ToDoubleRegister(instr->temp());
5201 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
5202 Register unclamped_reg = ToRegister(instr->unclamped());
5203 Register result_reg = ToRegister(instr->result());
5208 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
5210 Register input_reg = ToRegister(instr->unclamped());
5211 Register result_reg = ToRegister(instr->result());
5212 DoubleRegister temp_reg = ToDoubleRegister(instr->temp());
5224 DeoptimizeIf(ne, instr->environment(), input_reg,
5243 void LCodeGen::DoAllocate(LAllocate* instr) {
5246 DeferredAllocate(LCodeGen* codegen, LAllocate* instr)
5247 : LDeferredCode(codegen), instr_(instr) { }
5249 virtual LInstruction* instr() { return instr_; }
5255 new(zone()) DeferredAllocate(this, instr);
5257 Register result = ToRegister(instr->result());
5258 Register scratch = ToRegister(instr->temp1());
5259 Register scratch2 = ToRegister(instr->temp2());
5263 if (instr->hydrogen()->MustAllocateDoubleAligned()) {
5266 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5267 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation());
5268 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5270 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5271 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5274 if (instr->size()->IsConstantOperand()) {
5275 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5278 Register size = ToRegister(instr->size());
5289 if (instr->hydrogen()->MustPrefillWithFiller()) {
5290 if (instr->size()->IsConstantOperand()) {
5291 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5294 scratch = ToRegister(instr->size());
5310 void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
5311 Register result = ToRegister(instr->result());
5319 if (instr->size()->IsRegister()) {
5320 Register size = ToRegister(instr->size());
5325 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5329 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5330 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation());
5331 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5332 CallRuntimeFromDeferred(Runtime::kAllocateInOldPointerSpace, 1, instr);
5333 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5334 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5335 CallRuntimeFromDeferred(Runtime::kAllocateInOldDataSpace, 1, instr);
5337 CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr);
5343 void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
5344 ASSERT(ToRegister(instr->value()).is(a0));
5345 ASSERT(ToRegister(instr->result()).is(v0));
5347 CallRuntime(Runtime::kToFastProperties, 1, instr);
5351 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
5359 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
5360 __ LoadHeapObject(t3, instr->hydrogen()->literals());
5367 __ li(t2, Operand(Smi::FromInt(instr->hydrogen()->literal_index())));
5368 __ li(t1, Operand(instr->hydrogen()->pattern()));
5369 __ li(t0, Operand(instr->hydrogen()->flags()));
5371 CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr);
5384 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr);
5403 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
5406 bool pretenure = instr->hydrogen()->pretenure();
5407 if (!pretenure && instr->hydrogen()->has_no_literals()) {
5408 FastNewClosureStub stub(instr->hydrogen()->language_mode(),
5409 instr->hydrogen()->is_generator());
5410 __ li(a1, Operand(instr->hydrogen()->shared_info()));
5412 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
5414 __ li(a2, Operand(instr->hydrogen()->shared_info()));
5418 CallRuntime(Runtime::kNewClosure, 3, instr);
5423 void LCodeGen::DoTypeof(LTypeof* instr) {
5424 ASSERT(ToRegister(instr->result()).is(v0));
5425 Register input = ToRegister(instr->value());
5427 CallRuntime(Runtime::kTypeof, 1, instr);
5431 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
5432 Register input = ToRegister(instr->value());
5437 Condition final_branch_condition = EmitTypeofIs(instr->TrueLabel(chunk_),
5438 instr->FalseLabel(chunk_),
5440 instr->type_literal(),
5448 EmitBranch(instr, final_branch_condition, cmp1, cmp2);
5559 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
5560 Register temp1 = ToRegister(instr->temp());
5564 EmitBranch(instr, eq, temp1,
5604 void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
5607 ASSERT(instr->HasEnvironment());
5608 LEnvironment* env = instr->environment();
5614 void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
5615 Deoptimizer::BailoutType type = instr->hydrogen()->type();
5624 Comment(";;; deoptimize: %s", instr->hydrogen()->reason());
5625 DeoptimizeIf(al, instr->environment(), type, zero_reg, Operand(zero_reg));
5629 void LCodeGen::DoDummyUse(LDummyUse* instr) {
5634 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
5638 instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
5639 ASSERT(instr->HasEnvironment());
5640 LEnvironment* env = instr->environment();
5645 void LCodeGen::DoStackCheck(LStackCheck* instr) {
5648 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
5649 : LDeferredCode(codegen), instr_(instr) { }
5651 virtual LInstruction* instr() { return instr_; }
5656 ASSERT(instr->HasEnvironment());
5657 LEnvironment* env = instr->environment();
5660 if (instr->hydrogen()->is_function_entry()) {
5666 instr);
5673 ASSERT(instr->hydrogen()->is_backwards_branch());
5676 new(zone()) DeferredStackCheck(this, instr);
5681 __ bind(instr->done_label());
5682 deferred_stack_check->SetExit(instr->done_label());
5691 void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
5695 LEnvironment* environment = instr->environment();
5708 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
5709 Register result = ToRegister(instr->result());
5710 Register object = ToRegister(instr->object());
5712 DeoptimizeIf(eq, instr->environment(), object, Operand(at));
5716 DeoptimizeIf(eq, instr->environment(), object, Operand(null_value));
5719 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
5723 DeoptimizeIf(le, instr->environment(), a1, Operand(LAST_JS_PROXY_TYPE));
5735 CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr);
5740 DeoptimizeIf(ne, instr->environment(), a1, Operand(at));
5745 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) {
5746 Register map = ToRegister(instr->map());
5747 Register result = ToRegister(instr->result());
5759 FieldMemOperand(result, FixedArray::SizeFor(instr->idx())));
5760 DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg));
5766 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
5767 Register object = ToRegister(instr->value());
5768 Register map = ToRegister(instr->map());
5770 DeoptimizeIf(ne, instr->environment(), map, Operand(scratch0()));
5774 void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
5775 Register object = ToRegister(instr->object());
5776 Register index = ToRegister(instr->index());
5777 Register result = ToRegister(instr->result());