Lines Matching refs:instr

524     HInstruction* instr = HInstruction::cast(value);
525 VisitInstruction(instr);
532 LInstruction* LChunkBuilder::Define(LTemplateResultInstruction<1>* instr,
535 instr->set_result(result);
536 return instr;
541 LTemplateResultInstruction<1>* instr) {
542 return Define(instr,
548 LTemplateResultInstruction<1>* instr, int index) {
549 return Define(instr,
555 LTemplateResultInstruction<1>* instr) {
556 return Define(instr,
562 LTemplateResultInstruction<1>* instr, Register reg) {
563 return Define(instr, ToUnallocated(reg));
568 LTemplateResultInstruction<1>* instr, DoubleRegister reg) {
569 return Define(instr, ToUnallocated(reg));
573 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
577 instr->set_environment(CreateEnvironment(hydrogen_env,
580 return instr;
584 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
589 instr->VerifyCall();
591 instr->MarkAsCall();
592 instr = AssignPointerMap(instr);
601 if (needs_environment && !instr->HasEnvironment()) {
602 instr = AssignEnvironment(instr);
604 instr->environment()->set_has_been_used();
607 return instr;
611 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) {
612 ASSERT(!instr->HasPointerMap());
613 instr->set_pointer_map(new(zone()) LPointerMap(zone()));
614 return instr;
658 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) {
659 return new(zone()) LLabel(instr->block());
663 LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) {
664 return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value())));
668 LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) {
674 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
680 HBitwiseBinaryOperation* instr) {
681 if (instr->representation().IsSmiOrInteger32()) {
682 ASSERT(instr->left()->representation().Equals(instr->representation()));
683 ASSERT(instr->right()->representation().Equals(instr->representation()));
684 LOperand* left = UseRegisterAtStart(instr->left());
686 HValue* right_value = instr->right();
696 if (instr->representation().IsSmi() && constant_value > 0) {
697 does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToSmi);
707 does_deopt = !instr->CheckFlag(HInstruction::kUint32);
709 does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
717 return DoArithmeticT(op, instr);
723 HArithmeticBinaryOperation* instr) {
724 ASSERT(instr->representation().IsDouble());
725 ASSERT(instr->left()->representation().IsDouble());
726 ASSERT(instr->right()->representation().IsDouble());
728 LOperand* left = UseFixedDouble(instr->left(), d0);
729 LOperand* right = UseFixedDouble(instr->right(), d1);
731 return MarkAsCall(DefineFixedDouble(result, d0), instr);
733 LOperand* left = UseRegisterAtStart(instr->left());
734 LOperand* right = UseRegisterAtStart(instr->right());
742 HBinaryOperation* instr) {
743 HValue* left = instr->left();
744 HValue* right = instr->right();
747 LOperand* context = UseFixed(instr->context(), cp);
752 return MarkAsCall(DefineFixed(result, r0), instr);
827 LInstruction* instr = NULL;
830 instr = DefineAsRegister(new(zone()) LDummy());
833 instr = DefineAsRegister(new(zone())
848 instr = new(zone()) LGoto(successor);
850 instr = current->CompileToLithium(this);
857 if (instr != NULL) {
858 AddInstruction(instr, current);
865 void LChunkBuilder::AddInstruction(LInstruction* instr,
869 instr->set_hydrogen_value(hydrogen_val);
882 if (!(instr->ClobbersRegisters() &&
883 instr->ClobbersDoubleRegisters(isolate()))) {
886 for (UseIterator it(instr); !it.Done(); it.Advance()) {
890 if (instr->Output() != NULL) {
891 if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed;
893 for (TempIterator it(instr); !it.Done(); it.Advance()) {
901 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
902 instr = AssignPointerMap(instr);
904 if (FLAG_stress_environments && !instr->HasEnvironment()) {
905 instr = AssignEnvironment(instr);
907 chunk_->AddInstruction(instr, current_block_);
909 if (instr->IsCall()) {
914 instruction_needing_environment = instr;
931 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
932 return new(zone()) LGoto(instr->FirstSuccessor());
936 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
937 HValue* value = instr->value();
940 ToBooleanStub::Types expected = instr->expected_input_types();
955 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) {
960 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) {
961 ASSERT(instr->value()->representation().IsTagged());
962 LOperand* value = UseRegisterAtStart(instr->value());
968 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* instr) {
970 LOperand* value = UseRegister(instr->value());
981 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) {
982 LOperand* context = UseFixed(instr->context(), cp);
984 new(zone()) LInstanceOf(context, UseFixed(instr->left(), r0),
985 UseFixed(instr->right(), r1));
986 return MarkAsCall(DefineFixed(result, r0), instr);
991 HInstanceOfKnownGlobal* instr) {
994 UseFixed(instr->context(), cp),
995 UseFixed(instr->left(), r0),
997 return MarkAsCall(DefineFixed(result, r0), instr);
1001 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) {
1002 LOperand* receiver = UseRegisterAtStart(instr->receiver());
1003 LOperand* function = UseRegisterAtStart(instr->function());
1009 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
1010 LOperand* function = UseFixed(instr->function(), r1);
1011 LOperand* receiver = UseFixed(instr->receiver(), r0);
1012 LOperand* length = UseFixed(instr->length(), r2);
1013 LOperand* elements = UseFixed(instr->elements(), r3);
1018 return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY);
1022 LInstruction* LChunkBuilder::DoPushArguments(HPushArguments* instr) {
1023 int argc = instr->OperandCount();
1025 LOperand* argument = Use(instr->argument(i));
1026 AddInstruction(new(zone()) LPushArgument(argument), instr);
1041 HInnerAllocatedObject* instr) {
1042 LOperand* base_object = UseRegisterAtStart(instr->base_object());
1043 LOperand* offset = UseRegisterOrConstantAtStart(instr->offset());
1049 LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) {
1050 return instr->HasNoUses()
1056 LInstruction* LChunkBuilder::DoContext(HContext* instr) {
1057 if (instr->HasNoUses()) return NULL;
1067 LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) {
1068 LOperand* context = UseFixed(instr->context(), cp);
1069 return MarkAsCall(new(zone()) LDeclareGlobals(context), instr);
1074 HCallJSFunction* instr) {
1075 LOperand* function = UseFixed(instr->function(), r1);
1079 return MarkAsCall(DefineFixed(result, r0), instr);
1084 HCallWithDescriptor* instr) {
1085 const CallInterfaceDescriptor* descriptor = instr->descriptor();
1087 LOperand* target = UseRegisterOrConstantAtStart(instr->target());
1088 ZoneList<LOperand*> ops(instr->OperandCount(), zone());
1090 for (int i = 1; i < instr->OperandCount(); i++) {
1091 LOperand* op = UseFixed(instr->OperandAt(i),
1098 return MarkAsCall(DefineFixed(result, r0), instr);
1102 LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
1103 LOperand* context = UseFixed(instr->context(), cp);
1104 LOperand* function = UseFixed(instr->function(), r1);
1106 return MarkAsCall(DefineFixed(result, r0), instr, CANNOT_DEOPTIMIZE_EAGERLY);
1110 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
1111 switch (instr->op()) {
1112 case kMathFloor: return DoMathFloor(instr);
1113 case kMathRound: return DoMathRound(instr);
1114 case kMathAbs: return DoMathAbs(instr);
1115 case kMathLog: return DoMathLog(instr);
1116 case kMathExp: return DoMathExp(instr);
1117 case kMathSqrt: return DoMathSqrt(instr);
1118 case kMathPowHalf: return DoMathPowHalf(instr);
1119 case kMathClz32: return DoMathClz32(instr);
1127 LInstruction* LChunkBuilder::DoMathFloor(HUnaryMathOperation* instr) {
1128 LOperand* input = UseRegister(instr->value());
1134 LInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) {
1135 LOperand* input = UseRegister(instr->value());
1142 LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) {
1143 Representation r = instr->value()->representation();
1146 : UseFixed(instr->context(), cp);
1147 LOperand* input = UseRegister(instr->value());
1156 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) {
1157 ASSERT(instr->representation().IsDouble());
1158 ASSERT(instr->value()->representation().IsDouble());
1159 LOperand* input = UseFixedDouble(instr->value(), d0);
1160 return MarkAsCall(DefineFixedDouble(new(zone()) LMathLog(input), d0), instr);
1164 LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) {
1165 LOperand* input = UseRegisterAtStart(instr->value());
1171 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) {
1172 ASSERT(instr->representation().IsDouble());
1173 ASSERT(instr->value()->representation().IsDouble());
1174 LOperand* input = UseRegister(instr->value());
1183 LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) {
1184 LOperand* input = UseRegisterAtStart(instr->value());
1190 LInstruction* LChunkBuilder::DoMathPowHalf(HUnaryMathOperation* instr) {
1191 LOperand* input = UseRegisterAtStart(instr->value());
1197 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) {
1198 LOperand* context = UseFixed(instr->context(), cp);
1199 LOperand* constructor = UseFixed(instr->constructor(), r1);
1201 return MarkAsCall(DefineFixed(result, r0), instr);
1205 LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) {
1206 LOperand* context = UseFixed(instr->context(), cp);
1207 LOperand* constructor = UseFixed(instr->constructor(), r1);
1209 return MarkAsCall(DefineFixed(result, r0), instr);
1213 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
1214 LOperand* context = UseFixed(instr->context(), cp);
1215 LOperand* function = UseFixed(instr->function(), r1);
1217 return MarkAsCall(DefineFixed(call, r0), instr);
1221 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) {
1222 LOperand* context = UseFixed(instr->context(), cp);
1223 return MarkAsCall(DefineFixed(new(zone()) LCallRuntime(context), r0), instr);
1227 LInstruction* LChunkBuilder::DoRor(HRor* instr) {
1228 return DoShift(Token::ROR, instr);
1232 LInstruction* LChunkBuilder::DoShr(HShr* instr) {
1233 return DoShift(Token::SHR, instr);
1237 LInstruction* LChunkBuilder::DoSar(HSar* instr) {
1238 return DoShift(Token::SAR, instr);
1242 LInstruction* LChunkBuilder::DoShl(HShl* instr) {
1243 return DoShift(Token::SHL, instr);
1247 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) {
1248 if (instr->representation().IsSmiOrInteger32()) {
1249 ASSERT(instr->left()->representation().Equals(instr->representation()));
1250 ASSERT(instr->right()->representation().Equals(instr->representation()));
1251 ASSERT(instr->CheckFlag(HValue::kTruncatingToInt32));
1253 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
1254 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand());
1257 return DoArithmeticT(instr->op(), instr);
1262 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) {
1263 ASSERT(instr->representation().IsSmiOrInteger32());
1264 ASSERT(instr->left()->representation().Equals(instr->representation()));
1265 ASSERT(instr->right()->representation().Equals(instr->representation()));
1266 LOperand* dividend = UseRegister(instr->left());
1267 int32_t divisor = instr->right()->GetInteger32Constant();
1270 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1271 (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) ||
1272 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
1280 LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) {
1281 ASSERT(instr->representation().IsInteger32());
1282 ASSERT(instr->left()->representation().Equals(instr->representation()));
1283 ASSERT(instr->right()->representation().Equals(instr->representation()));
1284 LOperand* dividend = UseRegister(instr->left());
1285 int32_t divisor = instr->right()->GetInteger32Constant();
1289 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1290 !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
1297 LInstruction* LChunkBuilder::DoDivI(HDiv* instr) {
1298 ASSERT(instr->representation().IsSmiOrInteger32());
1299 ASSERT(instr->left()->representation().Equals(instr->representation()));
1300 ASSERT(instr->right()->representation().Equals(instr->representation()));
1301 LOperand* dividend = UseRegister(instr->left());
1302 LOperand* divisor = UseRegister(instr->right());
1307 if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1308 instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
1309 (instr->CheckFlag(HValue::kCanOverflow) &&
1311 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) ||
1312 (!instr->IsMathFloorOfDiv() &&
1313 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
1320 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
1321 if (instr->representation().IsSmiOrInteger32()) {
1322 if (instr->RightIsPowerOf2()) {
1323 return DoDivByPowerOf2I(instr);
1324 } else if (instr->right()->IsConstant()) {
1325 return DoDivByConstI(instr);
1327 return DoDivI(instr);
1329 } else if (instr->representation().IsDouble()) {
1330 return DoArithmeticD(Token::DIV, instr);
1332 return DoArithmeticT(Token::DIV, instr);
1337 LInstruction* LChunkBuilder::DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr) {
1338 LOperand* dividend = UseRegisterAtStart(instr->left());
1339 int32_t divisor = instr->right()->GetInteger32Constant();
1342 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1343 (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) {
1350 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) {
1351 ASSERT(instr->representation().IsInteger32());
1352 ASSERT(instr->left()->representation().Equals(instr->representation()));
1353 ASSERT(instr->right()->representation().Equals(instr->representation()));
1354 LOperand* dividend = UseRegister(instr->left());
1355 int32_t divisor = instr->right()->GetInteger32Constant();
1357 ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) ||
1358 (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ?
1363 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) {
1370 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) {
1371 ASSERT(instr->representation().IsSmiOrInteger32());
1372 ASSERT(instr->left()->representation().Equals(instr->representation()));
1373 ASSERT(instr->right()->representation().Equals(instr->representation()));
1374 LOperand* dividend = UseRegister(instr->left());
1375 LOperand* divisor = UseRegister(instr->right());
1383 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
1384 if (instr->RightIsPowerOf2()) {
1385 return DoFlooringDivByPowerOf2I(instr);
1386 } else if (instr->right()->IsConstant()) {
1387 return DoFlooringDivByConstI(instr);
1389 return DoFlooringDivI(instr);
1394 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) {
1395 ASSERT(instr->representation().IsSmiOrInteger32());
1396 ASSERT(instr->left()->representation().Equals(instr->representation()));
1397 ASSERT(instr->right()->representation().Equals(instr->representation()));
1398 LOperand* dividend = UseRegisterAtStart(instr->left());
1399 int32_t divisor = instr->right()->GetInteger32Constant();
1402 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1409 LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) {
1410 ASSERT(instr->representation().IsSmiOrInteger32());
1411 ASSERT(instr->left()->representation().Equals(instr->representation()));
1412 ASSERT(instr->right()->representation().Equals(instr->representation()));
1413 LOperand* dividend = UseRegister(instr->left());
1414 int32_t divisor = instr->right()->GetInteger32Constant();
1417 if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1424 LInstruction* LChunkBuilder::DoModI(HMod* instr) {
1425 ASSERT(instr->representation().IsSmiOrInteger32());
1426 ASSERT(instr->left()->representation().Equals(instr->representation()));
1427 ASSERT(instr->right()->representation().Equals(instr->representation()));
1428 LOperand* dividend = UseRegister(instr->left());
1429 LOperand* divisor = UseRegister(instr->right());
1436 if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1437 instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1444 LInstruction* LChunkBuilder::DoMod(HMod* instr) {
1445 if (instr->representation().IsSmiOrInteger32()) {
1446 if (instr->RightIsPowerOf2()) {
1447 return DoModByPowerOf2I(instr);
1448 } else if (instr->right()->IsConstant()) {
1449 return DoModByConstI(instr);
1451 return DoModI(instr);
1453 } else if (instr->representation().IsDouble()) {
1454 return DoArithmeticD(Token::MOD, instr);
1456 return DoArithmeticT(Token::MOD, instr);
1461 LInstruction* LChunkBuilder::DoMul(HMul* instr) {
1462 if (instr->representation().IsSmiOrInteger32()) {
1463 ASSERT(instr->left()->representation().Equals(instr->representation()));
1464 ASSERT(instr->right()->representation().Equals(instr->representation()));
1465 HValue* left = instr->BetterLeftOperand();
1466 HValue* right = instr->BetterRightOperand();
1469 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow);
1470 bool bailout_on_minus_zero = instr->CheckFlag(HValue::kBailoutOnMinusZero);
1502 } else if (instr->representation().IsDouble()) {
1503 if (instr->UseCount() == 1 && (instr->uses().value()->IsAdd() ||
1504 instr->uses().value()->IsSub())) {
1505 HBinaryOperation* use = HBinaryOperation::cast(instr->uses().value());
1507 if (use->IsAdd() && instr == use->left()) {
1512 if (instr == use->right() && use->IsAdd() && !use->left()->IsMul()) {
1517 if (instr == use->right() && use->IsSub()) {
1524 return DoArithmeticD(Token::MUL, instr);
1526 return DoArithmeticT(Token::MUL, instr);
1531 LInstruction* LChunkBuilder::DoSub(HSub* instr) {
1532 if (instr->representation().IsSmiOrInteger32()) {
1533 ASSERT(instr->left()->representation().Equals(instr->representation()));
1534 ASSERT(instr->right()->representation().Equals(instr->representation()));
1536 if (instr->left()->IsConstant()) {
1538 return DoRSub(instr);
1541 LOperand* left = UseRegisterAtStart(instr->left());
1542 LOperand* right = UseOrConstantAtStart(instr->right());
1545 if (instr->CheckFlag(HValue::kCanOverflow)) {
1549 } else if (instr->representation().IsDouble()) {
1550 if (instr->right()->IsMul()) {
1551 return DoMultiplySub(instr->left(), HMul::cast(instr->right()));
1554 return DoArithmeticD(Token::SUB, instr);
1556 return DoArithmeticT(Token::SUB, instr);
1561 LInstruction* LChunkBuilder::DoRSub(HSub* instr) {
1562 ASSERT(instr->representation().IsSmiOrInteger32());
1563 ASSERT(instr->left()->representation().Equals(instr->representation()));
1564 ASSERT(instr->right()->representation().Equals(instr->representation()));
1568 LOperand* left = UseRegisterAtStart(instr->right());
1569 LOperand* right = UseOrConstantAtStart(instr->left());
1572 if (instr->CheckFlag(HValue::kCanOverflow)) {
1599 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
1600 if (instr->representation().IsSmiOrInteger32()) {
1601 ASSERT(instr->left()->representation().Equals(instr->representation()));
1602 ASSERT(instr->right()->representation().Equals(instr->representation()));
1603 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
1604 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand());
1607 if (instr->CheckFlag(HValue::kCanOverflow)) {
1611 } else if (instr->representation().IsExternal()) {
1612 ASSERT(instr->left()->representation().IsExternal());
1613 ASSERT(instr->right()->representation().IsInteger32());
1614 ASSERT(!instr->CheckFlag(HValue::kCanOverflow));
1615 LOperand* left = UseRegisterAtStart(instr->left());
1616 LOperand* right = UseOrConstantAtStart(instr->right());
1620 } else if (instr->representation().IsDouble()) {
1621 if (instr->left()->IsMul()) {
1622 return DoMultiplyAdd(HMul::cast(instr->left()), instr->right());
1625 if (instr->right()->IsMul()) {
1626 ASSERT(!instr->left()->IsMul());
1627 return DoMultiplyAdd(HMul::cast(instr->right()), instr->left());
1630 return DoArithmeticD(Token::ADD, instr);
1632 return DoArithmeticT(Token::ADD, instr);
1637 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) {
1640 if (instr->representation().IsSmiOrInteger32()) {
1641 ASSERT(instr->left()->representation().Equals(instr->representation()));
1642 ASSERT(instr->right()->representation().Equals(instr->representation()));
1643 left = UseRegisterAtStart(instr->BetterLeftOperand());
1644 right = UseOrConstantAtStart(instr->BetterRightOperand());
1646 ASSERT(instr->representation().IsDouble());
1647 ASSERT(instr->left()->representation().IsDouble());
1648 ASSERT(instr->right()->representation().IsDouble());
1649 left = UseRegisterAtStart(instr->left());
1650 right = UseRegisterAtStart(instr->right());
1656 LInstruction* LChunkBuilder::DoPower(HPower* instr) {
1657 ASSERT(instr->representation().IsDouble());
1660 Representation exponent_type = instr->right()->representation();
1661 ASSERT(instr->left()->representation().IsDouble());
1662 LOperand* left = UseFixedDouble(instr->left(), d0);
1664 UseFixedDouble(instr->right(), d1) :
1665 UseFixed(instr->right(), r2);
1668 instr,
1673 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
1674 ASSERT(instr->left()->representation().IsTagged());
1675 ASSERT(instr->right()->representation().IsTagged());
1676 LOperand* context = UseFixed(instr->context(), cp);
1677 LOperand* left = UseFixed(instr->left(), r1);
1678 LOperand* right = UseFixed(instr->right(), r0);
1680 return MarkAsCall(DefineFixed(result, r0), instr);
1685 HCompareNumericAndBranch* instr) {
1686 Representation r = instr->representation();
1688 ASSERT(instr->left()->representation().Equals(r));
1689 ASSERT(instr->right()->representation().Equals(r));
1690 LOperand* left = UseRegisterOrConstantAtStart(instr->left());
1691 LOperand* right = UseRegisterOrConstantAtStart(instr->right());
1695 ASSERT(instr->left()->representation().IsDouble());
1696 ASSERT(instr->right()->representation().IsDouble());
1697 LOperand* left = UseRegisterAtStart(instr->left());
1698 LOperand* right = UseRegisterAtStart(instr->right());
1705 HCompareObjectEqAndBranch* instr) {
1706 LOperand* left = UseRegisterAtStart(instr->left());
1707 LOperand* right = UseRegisterAtStart(instr->right());
1713 HCompareHoleAndBranch* instr) {
1714 LOperand* value = UseRegisterAtStart(instr->value());
1720 HCompareMinusZeroAndBranch* instr) {
1721 LOperand* value = UseRegister(instr->value());
1727 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) {
1728 ASSERT(instr->value()->representation().IsTagged());
1729 LOperand* value = UseRegisterAtStart(instr->value());
1735 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) {
1736 ASSERT(instr->value()->representation().IsTagged());
1737 LOperand* value = UseRegisterAtStart(instr->value());
1743 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) {
1744 ASSERT(instr->value()->representation().IsTagged());
1745 return new(zone()) LIsSmiAndBranch(Use(instr->value()));
1750 HIsUndetectableAndBranch* instr) {
1751 ASSERT(instr->value()->representation().IsTagged());
1752 LOperand* value = UseRegisterAtStart(instr->value());
1758 HStringCompareAndBranch* instr) {
1759 ASSERT(instr->left()->representation().IsTagged());
1760 ASSERT(instr->right()->representation().IsTagged());
1761 LOperand* context = UseFixed(instr->context(), cp);
1762 LOperand* left = UseFixed(instr->left(), r1);
1763 LOperand* right = UseFixed(instr->right(), r0);
1766 return MarkAsCall(result, instr);
1771 HHasInstanceTypeAndBranch* instr) {
1772 ASSERT(instr->value()->representation().IsTagged());
1773 LOperand* value = UseRegisterAtStart(instr->value());
1779 HGetCachedArrayIndex* instr) {
1780 ASSERT(instr->value()->representation().IsTagged());
1781 LOperand* value = UseRegisterAtStart(instr->value());
1788 HHasCachedArrayIndexAndBranch* instr) {
1789 ASSERT(instr->value()->representation().IsTagged());
1791 UseRegisterAtStart(instr->value()));
1796 HClassOfTestAndBranch* instr) {
1797 ASSERT(instr->value()->representation().IsTagged());
1798 LOperand* value = UseRegister(instr->value());
1803 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) {
1804 LOperand* map = UseRegisterAtStart(instr->value());
1809 LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
1810 LOperand* object = UseFixed(instr->value(), r0);
1812 new(zone()) LDateField(object, FixedTemp(r1), instr->index());
1813 return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY);
1817 LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) {
1818 LOperand* string = UseRegisterAtStart(instr->string());
1819 LOperand* index = UseRegisterOrConstantAtStart(instr->index());
1824 LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) {
1825 LOperand* string = UseRegisterAtStart(instr->string());
1827 ? UseRegisterAtStart(instr->index())
1828 : UseRegisterOrConstantAtStart(instr->index());
1829 LOperand* value = UseRegisterAtStart(instr->value());
1830 LOperand* context = FLAG_debug_code ? UseFixed(instr->context(), cp) : NULL;
1835 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
1836 if (!FLAG_debug_code && instr->skip_check()) return NULL;
1837 LOperand* index = UseRegisterOrConstantAtStart(instr->index());
1839 ? UseRegisterOrConstantAtStart(instr->length())
1840 : UseRegisterAtStart(instr->length());
1842 if (!FLAG_debug_code || !instr->skip_check()) {
1850 HBoundsCheckBaseIndexInformation* instr) {
1856 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
1863 LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) {
1876 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1877 Representation from = instr->from();
1878 Representation to = instr->to();
1879 HValue* val = instr->value();
1931 if (!instr->CanTruncateToInt32()) result = AssignEnvironment(result);
1937 if (!instr->CheckFlag(HValue::kCanOverflow)) {
1956 if (instr->CheckFlag(HValue::kCanOverflow)) {
1974 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
1975 LOperand* value = UseRegisterAtStart(instr->value());
1977 if (!instr->value()->type().IsHeapObject()) {
1984 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) {
1985 LOperand* value = UseRegisterAtStart(instr->value());
1990 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
1991 LOperand* value = UseRegisterAtStart(instr->value());
1997 LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) {
1998 LOperand* value = UseRegisterAtStart(instr->value());
2003 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
2004 if (instr->IsStabilityCheck()) return new(zone()) LCheckMaps;
2005 LOperand* value = UseRegisterAtStart(instr->value());
2007 if (instr->HasMigrationTarget()) {
2015 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
2016 HValue* value = instr->value();
2034 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) {
2035 HValue* value = instr->value();
2041 LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) {
2042 LOperand* lo = UseRegister(instr->lo());
2043 LOperand* hi = UseRegister(instr->hi());
2048 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
2050 ? UseFixed(instr->context(), cp)
2052 LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count());
2053 return new(zone()) LReturn(UseFixed(instr->value(), r0), context,
2058 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
2059 Representation r = instr->representation();
2077 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
2079 return instr->RequiresHoleCheck()
2085 LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
2086 LOperand* context = UseFixed(instr->context(), cp);
2087 LOperand* global_object = UseFixed(instr->global_object(), r0);
2090 return MarkAsCall(DefineFixed(result, r0), instr);
2094 LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
2095 LOperand* value = UseRegister(instr->value());
2098 return instr->RequiresHoleCheck()
2104 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
2105 LOperand* context = UseRegisterAtStart(instr->value());
2108 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
2115 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
2118 if (instr->NeedsWriteBarrier()) {
2119 context = UseTempRegister(instr->context());
2120 value = UseTempRegister(instr->value());
2122 context = UseRegister(instr->context());
2123 value = UseRegister(instr->value());
2126 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
2133 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
2134 LOperand* obj = UseRegisterAtStart(instr->object());
2139 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
2140 LOperand* context = UseFixed(instr->context(), cp);
2141 LOperand* object = UseFixed(instr->object(), r0);
2144 return MarkAsCall(result, instr);
2149 HLoadFunctionPrototype* instr) {
2151 new(zone()) LLoadFunctionPrototype(UseRegister(instr->function()))));
2155 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) {
2160 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
2161 ASSERT(instr->key()->representation().IsSmiOrInteger32());
2162 ElementsKind elements_kind = instr->elements_kind();
2163 LOperand* key = UseRegisterOrConstantAtStart(instr->key());
2166 if (!instr->is_typed_elements()) {
2168 if (instr->representation().IsDouble()) {
2169 obj = UseRegister(instr->elements());
2171 ASSERT(instr->representation().IsSmiOrTagged());
2172 obj = UseRegisterAtStart(instr->elements());
2177 (instr->representation().IsInteger32() &&
2179 (instr->representation().IsDouble() &&
2181 LOperand* backing_store = UseRegister(instr->elements());
2185 if ((instr->is_external() || instr->is_fixed_typed_array()) ?
2189 !instr->CheckFlag(HInstruction::kUint32)) :
2192 instr->RequiresHoleCheck()) {
2199 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
2200 LOperand* context = UseFixed(instr->context(), cp);
2201 LOperand* object = UseFixed(instr->object(), r1);
2202 LOperand* key = UseFixed(instr->key(), r0);
2206 return MarkAsCall(result, instr);
2210 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
2211 if (!instr->is_typed_elements()) {
2212 ASSERT(instr->elements()->representation().IsTagged());
2213 bool needs_write_barrier = instr->NeedsWriteBarrier();
2218 if (instr->value()->representation().IsDouble()) {
2219 object = UseRegisterAtStart(instr->elements());
2220 val = UseRegister(instr->value());
2221 key = UseRegisterOrConstantAtStart(instr->key());
2223 ASSERT(instr->value()->representation().IsSmiOrTagged());
2225 object = UseTempRegister(instr->elements());
2226 val = UseTempRegister(instr->value());
2227 key = UseTempRegister(instr->key());
2229 object = UseRegisterAtStart(instr->elements());
2230 val = UseRegisterAtStart(instr->value());
2231 key = UseRegisterOrConstantAtStart(instr->key());
2239 (instr->value()->representation().IsInteger32() &&
2240 !IsDoubleOrFloatElementsKind(instr->elements_kind())) ||
2241 (instr->value()->representation().IsDouble() &&
2242 IsDoubleOrFloatElementsKind(instr->elements_kind())));
2243 ASSERT((instr->is_fixed_typed_array() &&
2244 instr->elements()->representation().IsTagged()) ||
2245 (instr->is_external() &&
2246 instr->elements()->representation().IsExternal()));
2247 LOperand* val = UseRegister(instr->value());
2248 LOperand* key = UseRegisterOrConstantAtStart(instr->key());
2249 LOperand* backing_store = UseRegister(instr->elements());
2254 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
2255 LOperand* context = UseFixed(instr->context(), cp);
2256 LOperand* obj = UseFixed(instr->object(), r2);
2257 LOperand* key = UseFixed(instr->key(), r1);
2258 LOperand* val = UseFixed(instr->value(), r0);
2260 ASSERT(instr->object()->representation().IsTagged());
2261 ASSERT(instr->key()->representation().IsTagged());
2262 ASSERT(instr->value()->representation().IsTagged());
2265 new(zone()) LStoreKeyedGeneric(context, obj, key, val), instr);
2270 HTransitionElementsKind* instr) {
2271 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
2272 LOperand* object = UseRegister(instr->object());
2278 LOperand* object = UseFixed(instr->object(), r0);
2279 LOperand* context = UseFixed(instr->context(), cp);
2282 return MarkAsCall(result, instr);
2288 HTrapAllocationMemento* instr) {
2289 LOperand* object = UseRegister(instr->object());
2297 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
2298 bool is_in_object = instr->access().IsInobject();
2299 bool needs_write_barrier = instr->NeedsWriteBarrier();
2300 bool needs_write_barrier_for_map = instr->has_transition() &&
2301 instr->NeedsWriteBarrierForMap();
2306 ? UseRegister(instr->object())
2307 : UseTempRegister(instr->object());
2310 ? UseRegister(instr->object())
2311 : UseRegisterAtStart(instr->object());
2315 if (needs_write_barrier || instr->field_representation().IsSmi()) {
2316 val = UseTempRegister(instr->value());
2317 } else if (instr->field_representation().IsDouble()) {
2318 val = UseRegisterAtStart(instr->value());
2320 val = UseRegister(instr->value());
2330 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
2331 LOperand* context = UseFixed(instr->context(), cp);
2332 LOperand* obj = UseFixed(instr->object(), r1);
2333 LOperand* val = UseFixed(instr->value(), r0);
2336 return MarkAsCall(result, instr);
2340 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) {
2341 LOperand* context = UseFixed(instr->context(), cp);
2342 LOperand* left = UseFixed(instr->left(), r1);
2343 LOperand* right = UseFixed(instr->right(), r0);
2346 instr);
2350 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
2351 LOperand* string = UseTempRegister(instr->string());
2352 LOperand* index = UseTempRegister(instr->index());
2353 LOperand* context = UseAny(instr->context());
2360 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
2361 LOperand* char_code = UseRegister(instr->value());
2362 LOperand* context = UseAny(instr->context());
2369 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) {
2371 LOperand* context = UseAny(instr->context());
2372 LOperand* size = instr->size()->IsConstant()
2373 ? UseConstant(instr->size())
2374 : UseTempRegister(instr->size());
2382 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) {
2383 LOperand* context = UseFixed(instr->context(), cp);
2385 DefineFixed(new(zone()) LRegExpLiteral(context), r0), instr);
2389 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) {
2390 LOperand* context = UseFixed(instr->context(), cp);
2392 DefineFixed(new(zone()) LFunctionLiteral(context), r0), instr);
2396 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
2399 current_block_->last_environment()->set_ast_id(instr->ast_id());
2404 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
2406 if (instr->kind() == HParameter::STACK_PARAMETER) {
2407 int spill_index = chunk()->GetParameterStackSlot(instr->index());
2413 int index = static_cast<int>(instr->index());
2420 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
2423 int env_index = instr->index();
2425 if (instr->environment()->is_parameter_index(env_index)) {
2428 spill_index = env_index - instr->environment()->first_local_index();
2438 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) {
2439 LOperand* context = UseFixed(instr->context(), cp);
2440 return MarkAsCall(DefineFixed(new(zone()) LCallStub(context), r0), instr);
2444 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
2453 LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) {
2454 instr->ReplayEnvironment(current_block_->last_environment());
2461 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
2463 LOperand* args = UseRegister(instr->arguments());
2464 LOperand* length = UseRegisterOrConstantAtStart(instr->length());
2465 LOperand* index = UseRegisterOrConstantAtStart(instr->index());
2470 LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) {
2471 LOperand* object = UseFixed(instr->value(), r0);
2473 return MarkAsCall(DefineFixed(result, r0), instr);
2477 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
2478 LOperand* context = UseFixed(instr->context(), cp);
2479 LTypeof* result = new(zone()) LTypeof(context, UseFixed(instr->value(), r0));
2480 return MarkAsCall(DefineFixed(result, r0), instr);
2484 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
2485 return new(zone()) LTypeofIsAndBranch(UseRegister(instr->value()));
2490 HIsConstructCallAndBranch* instr) {
2495 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
2496 instr->ReplayEnvironment(current_block_->last_environment());
2501 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
2502 if (instr->is_function_entry()) {
2503 LOperand* context = UseFixed(instr->context(), cp);
2504 return MarkAsCall(new(zone()) LStackCheck(context), instr);
2506 ASSERT(instr->is_backwards_branch());
2507 LOperand* context = UseAny(instr->context());
2514 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
2516 outer->set_ast_id(instr->ReturnId());
2518 HEnvironment* inner = outer->CopyForInlining(instr->closure(),
2519 instr->arguments_count(),
2520 instr->function(),
2522 instr->inlining_kind());
2524 if (instr->arguments_var() != NULL && instr->arguments_object()->IsLinked()) {
2525 inner->Bind(instr->arguments_var(), instr->arguments_object());
2527 inner->set_entry(instr);
2529 chunk_->AddInlinedClosure(instr->closure());
2534 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
2542 ASSERT(instr->argument_delta() == -argument_count);
2553 LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) {
2554 LOperand* context = UseFixed(instr->context(), cp);
2555 LOperand* object = UseFixed(instr->enumerable(), r0);
2557 return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY);
2561 LInstruction* LChunkBuilder::DoForInCacheArray(HForInCacheArray* instr) {
2562 LOperand* map = UseRegister(instr->map());
2567 LInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) {
2568 LOperand* value = UseRegisterAtStart(instr->value());
2569 LOperand* map = UseRegisterAtStart(instr->map());
2574 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
2575 LOperand* object = UseRegister(instr->object());
2576 LOperand* index = UseTempRegister(instr->index());
2583 LInstruction* LChunkBuilder::DoStoreFrameContext(HStoreFrameContext* instr) {
2584 LOperand* context = UseRegisterAtStart(instr->context());
2590 HAllocateBlockContext* instr) {
2591 LOperand* context = UseFixed(instr->context(), cp);
2592 LOperand* function = UseRegisterAtStart(instr->function());
2595 return MarkAsCall(DefineFixed(result, cp), instr);