Lines Matching refs:instr

569     HInstruction* instr = HInstruction::cast(value);
570 VisitInstruction(instr);
577 LInstruction* LChunkBuilder::Define(LTemplateResultInstruction<1>* instr,
580 instr->set_result(result);
581 return instr;
586 LTemplateResultInstruction<1>* instr) {
587 return Define(instr,
593 LTemplateResultInstruction<1>* instr,
595 return Define(instr,
601 LTemplateResultInstruction<1>* instr) {
602 return Define(instr,
607 LInstruction* LChunkBuilder::DefineFixed(LTemplateResultInstruction<1>* instr,
609 return Define(instr, ToUnallocated(reg));
614 LTemplateResultInstruction<1>* instr,
616 return Define(instr, ToUnallocated(reg));
620 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
624 instr->set_environment(CreateEnvironment(
626 return instr;
630 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
636 instr->VerifyCall();
638 instr->MarkAsCall();
639 instr = AssignPointerMap(instr);
648 if (needs_environment && !instr->HasEnvironment()) {
649 instr = AssignEnvironment(instr);
651 instr->environment()->set_has_been_used();
654 return instr;
658 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) {
659 DCHECK(!instr->HasPointerMap());
660 instr->set_pointer_map(new(zone()) LPointerMap(zone()));
661 return instr;
692 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) {
693 return new(zone()) LLabel(instr->block());
697 LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) {
698 return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value())));
702 LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) {
708 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
714 HBitwiseBinaryOperation* instr) {
715 if (instr->representation().IsSmiOrInteger32()) {
716 DCHECK(instr->left()->representation().Equals(instr->representation()));
717 DCHECK(instr->right()->representation().Equals(instr->representation()));
718 LOperand* left = UseRegisterAtStart(instr->left());
720 HValue* right_value = instr->right();
730 if (instr->representation().IsSmi() && constant_value > 0) {
731 does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToSmi);
741 does_deopt = !instr->CheckFlag(HInstruction::kUint32);
743 does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
751 return DoArithmeticT(op, instr);
757 HArithmeticBinaryOperation* instr) {
758 DCHECK(instr->representation().IsDouble());
759 DCHECK(instr->left()->representation().IsDouble());
760 DCHECK(instr->right()->representation().IsDouble());
762 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
763 LOperand* right = UseRegisterAtStart(instr->BetterRightOperand());
765 return MarkAsCall(DefineSameAsFirst(result), instr);
767 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
768 LOperand* right = UseRegisterAtStart(instr->BetterRightOperand());
776 HBinaryOperation* instr) {
777 HValue* left = instr->left();
778 HValue* right = instr->right();
781 LOperand* context = UseFixed(instr->context(), esi);
786 return MarkAsCall(DefineFixed(result, eax), instr);
861 LInstruction* instr = NULL;
864 instr = DefineAsRegister(new(zone()) LDummy());
867 instr = DefineAsRegister(new(zone())
882 instr = new(zone()) LGoto(successor);
884 instr = current->CompileToLithium(this);
891 if (instr != NULL) {
892 AddInstruction(instr, current);
899 void LChunkBuilder::AddInstruction(LInstruction* instr,
903 instr->set_hydrogen_value(hydrogen_val);
916 if (!(instr->ClobbersRegisters() &&
917 instr->ClobbersDoubleRegisters(isolate()))) {
920 for (UseIterator it(instr); !it.Done(); it.Advance()) {
924 if (instr->Output() != NULL) {
925 if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed;
927 for (TempIterator it(instr); !it.Done(); it.Advance()) {
935 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
936 instr = AssignPointerMap(instr);
938 if (FLAG_stress_environments && !instr->HasEnvironment()) {
939 instr = AssignEnvironment(instr);
941 chunk_->AddInstruction(instr, current_block_);
943 if (instr->IsCall()) {
948 instruction_needing_environment = instr;
965 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
966 return new(zone()) LGoto(instr->FirstSuccessor());
970 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
971 HValue* value = instr->value();
974 ToBooleanStub::Types expected = instr->expected_input_types();
990 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) {
995 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) {
996 DCHECK(instr->value()->representation().IsTagged());
997 LOperand* value = UseRegisterAtStart(instr->value());
1014 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) {
1015 LOperand* left = UseFixed(instr->left(), InstanceofStub::left());
1016 LOperand* right = UseFixed(instr->right(), InstanceofStub::right());
1017 LOperand* context = UseFixed(instr->context(), esi);
1019 return MarkAsCall(DefineFixed(result, eax), instr);
1024 HInstanceOfKnownGlobal* instr) {
1027 UseFixed(instr->context(), esi),
1028 UseFixed(instr->left(), InstanceofStub::left()),
1030 return MarkAsCall(DefineFixed(result, eax), instr);
1034 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) {
1035 LOperand* receiver = UseRegister(instr->receiver());
1036 LOperand* function = UseRegister(instr->function());
1044 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
1045 LOperand* function = UseFixed(instr->function(), edi);
1046 LOperand* receiver = UseFixed(instr->receiver(), eax);
1047 LOperand* length = UseFixed(instr->length(), ebx);
1048 LOperand* elements = UseFixed(instr->elements(), ecx);
1053 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY);
1057 LInstruction* LChunkBuilder::DoPushArguments(HPushArguments* instr) {
1058 int argc = instr->OperandCount();
1060 LOperand* argument = UseAny(instr->argument(i));
1061 AddInstruction(new(zone()) LPushArgument(argument), instr);
1076 HInnerAllocatedObject* instr) {
1077 LOperand* base_object = UseRegisterAtStart(instr->base_object());
1078 LOperand* offset = UseRegisterOrConstantAtStart(instr->offset());
1084 LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) {
1085 return instr->HasNoUses()
1091 LInstruction* LChunkBuilder::DoContext(HContext* instr) {
1092 if (instr->HasNoUses()) return NULL;
1102 LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) {
1103 LOperand* context = UseFixed(instr->context(), esi);
1104 return MarkAsCall(new(zone()) LDeclareGlobals(context), instr);
1109 HCallJSFunction* instr) {
1110 LOperand* function = UseFixed(instr->function(), edi);
1114 return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
1119 HCallWithDescriptor* instr) {
1120 CallInterfaceDescriptor descriptor = instr->descriptor();
1121 LOperand* target = UseRegisterOrConstantAtStart(instr->target());
1122 ZoneList<LOperand*> ops(instr->OperandCount(), zone());
1124 for (int i = 1; i < instr->OperandCount(); i++) {
1126 UseFixed(instr->OperandAt(i), descriptor.GetParameterRegister(i - 1));
1132 return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
1137 HTailCallThroughMegamorphicCache* instr) {
1138 LOperand* context = UseFixed(instr->context(), esi);
1140 UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
1142 UseFixed(instr->name(), LoadDescriptor::NameRegister());
1149 LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
1150 LOperand* context = UseFixed(instr->context(), esi);
1151 LOperand* function = UseFixed(instr->function(), edi);
1153 return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
1157 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
1158 switch (instr->op()) {
1160 return DoMathFloor(instr);
1162 return DoMathRound(instr);
1164 return DoMathFround(instr);
1166 return DoMathAbs(instr);
1168 return DoMathLog(instr);
1170 return DoMathExp(instr);
1172 return DoMathSqrt(instr);
1174 return DoMathPowHalf(instr);
1176 return DoMathClz32(instr);
1184 LInstruction* LChunkBuilder::DoMathFloor(HUnaryMathOperation* instr) {
1185 LOperand* input = UseRegisterAtStart(instr->value());
1191 LInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) {
1192 LOperand* input = UseRegister(instr->value());
1199 LInstruction* LChunkBuilder::DoMathFround(HUnaryMathOperation* instr) {
1200 LOperand* input = UseRegister(instr->value());
1206 LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) {
1207 LOperand* context = UseAny(instr->context()); // Deferred use.
1208 LOperand* input = UseRegisterAtStart(instr->value());
1211 Representation r = instr->value()->representation();
1218 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) {
1219 DCHECK(instr->representation().IsDouble());
1220 DCHECK(instr->value()->representation().IsDouble());
1221 LOperand* input = UseRegisterAtStart(instr->value());
1222 return MarkAsCall(DefineSameAsFirst(new(zone()) LMathLog(input)), instr);
1226 LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) {
1227 LOperand* input = UseRegisterAtStart(instr->value());
1233 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) {
1234 DCHECK(instr->representation().IsDouble());
1235 DCHECK(instr->value()->representation().IsDouble());
1236 LOperand* value = UseTempRegister(instr->value());
1244 LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) {
1245 LOperand* input = UseAtStart(instr->value());
1250 LInstruction* LChunkBuilder::DoMathPowHalf(HUnaryMathOperation* instr) {
1251 LOperand* input = UseRegisterAtStart(instr->value());
1258 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) {
1259 LOperand* context = UseFixed(instr->context(), esi);
1260 LOperand* constructor = UseFixed(instr->constructor(), edi);
1262 return MarkAsCall(DefineFixed(result, eax), instr);
1266 LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) {
1267 LOperand* context = UseFixed(instr->context(), esi);
1268 LOperand* constructor = UseFixed(instr->constructor(), edi);
1270 return MarkAsCall(DefineFixed(result, eax), instr);
1274 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
1275 LOperand* context = UseFixed(instr->context(), esi);
1276 LOperand* function = UseFixed(instr->function(), edi);
1278 return MarkAsCall(DefineFixed(call, eax), instr);
1282 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) {
1283 LOperand* context = UseFixed(instr->context(), esi);
1284 return MarkAsCall(DefineFixed(new(zone()) LCallRuntime(context), eax), instr);
1288 LInstruction* LChunkBuilder::DoRor(HRor* instr) {
1289 return DoShift(Token::ROR, instr);
1293 LInstruction* LChunkBuilder::DoShr(HShr* instr) {
1294 return DoShift(Token::SHR, instr);
1298 LInstruction* LChunkBuilder::DoSar(HSar* instr) {
1299 return DoShift(Token::SAR, instr);
1303 LInstruction* LChunkBuilder::DoShl(HShl* instr) {
1304 return DoShift(Token::SHL, instr);
1308 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) {
1309 if (instr->representation().IsSmiOrInteger32()) {
1310 DCHECK(instr->left()->representation().Equals(instr->representation()));
1311 DCHECK(instr->right()->representation().Equals(instr->representation()));
1312 DCHECK(instr->CheckFlag(HValue::kTruncatingToInt32));
1314 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
1315 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand());
1318 return DoArithmeticT(instr->op(), instr);
1323 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) {
1324 DCHECK(instr->representation().IsSmiOrInteger32());
1325 DCHECK(instr->left()->representation().Equals(instr->representation()));
1326 DCHECK(instr->right()->representation().Equals(instr->representation()));
1327 LOperand* dividend = UseRegister(instr->left());
1328 int32_t divisor = instr->right()->GetInteger32Constant();
1331 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1332 (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) ||
1333 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
1341 LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) {
1342 DCHECK(instr->representation().IsInteger32());
1343 DCHECK(instr->left()->representation().Equals(instr->representation()));
1344 DCHECK(instr->right()->representation().Equals(instr->representation()));
1345 LOperand* dividend = UseRegister(instr->left());
1346 int32_t divisor = instr->right()->GetInteger32Constant();
1352 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1353 !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
1360 LInstruction* LChunkBuilder::DoDivI(HDiv* instr) {
1361 DCHECK(instr->representation().IsSmiOrInteger32());
1362 DCHECK(instr->left()->representation().Equals(instr->representation()));
1363 DCHECK(instr->right()->representation().Equals(instr->representation()));
1364 LOperand* dividend = UseFixed(instr->left(), eax);
1365 LOperand* divisor = UseRegister(instr->right());
1369 if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1370 instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
1371 instr->CheckFlag(HValue::kCanOverflow) ||
1372 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
1379 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
1380 if (instr->representation().IsSmiOrInteger32()) {
1381 if (instr->RightIsPowerOf2()) {
1382 return DoDivByPowerOf2I(instr);
1383 } else if (instr->right()->IsConstant()) {
1384 return DoDivByConstI(instr);
1386 return DoDivI(instr);
1388 } else if (instr->representation().IsDouble()) {
1389 return DoArithmeticD(Token::DIV, instr);
1391 return DoArithmeticT(Token::DIV, instr);
1396 LInstruction* LChunkBuilder::DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr) {
1397 LOperand* dividend = UseRegisterAtStart(instr->left());
1398 int32_t divisor = instr->right()->GetInteger32Constant();
1401 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1402 (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) {
1409 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) {
1410 DCHECK(instr->representation().IsInteger32());
1411 DCHECK(instr->left()->representation().Equals(instr->representation()));
1412 DCHECK(instr->right()->representation().Equals(instr->representation()));
1413 LOperand* dividend = UseRegister(instr->left());
1414 int32_t divisor = instr->right()->GetInteger32Constant();
1418 ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) ||
1419 (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ?
1429 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) {
1436 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) {
1437 DCHECK(instr->representation().IsSmiOrInteger32());
1438 DCHECK(instr->left()->representation().Equals(instr->representation()));
1439 DCHECK(instr->right()->representation().Equals(instr->representation()));
1440 LOperand* dividend = UseFixed(instr->left(), eax);
1441 LOperand* divisor = UseRegister(instr->right());
1445 if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1446 instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
1447 instr->CheckFlag(HValue::kCanOverflow)) {
1454 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
1455 if (instr->RightIsPowerOf2()) {
1456 return DoFlooringDivByPowerOf2I(instr);
1457 } else if (instr->right()->IsConstant()) {
1458 return DoFlooringDivByConstI(instr);
1460 return DoFlooringDivI(instr);
1465 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) {
1466 DCHECK(instr->representation().IsSmiOrInteger32());
1467 DCHECK(instr->left()->representation().Equals(instr->representation()));
1468 DCHECK(instr->right()->representation().Equals(instr->representation()));
1469 LOperand* dividend = UseRegisterAtStart(instr->left());
1470 int32_t divisor = instr->right()->GetInteger32Constant();
1473 if (instr->CheckFlag(HValue::kLeftCanBeNegative) &&
1474 instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1481 LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) {
1482 DCHECK(instr->representation().IsSmiOrInteger32());
1483 DCHECK(instr->left()->representation().Equals(instr->representation()));
1484 DCHECK(instr->right()->representation().Equals(instr->representation()));
1485 LOperand* dividend = UseRegister(instr->left());
1486 int32_t divisor = instr->right()->GetInteger32Constant();
1491 if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1498 LInstruction* LChunkBuilder::DoModI(HMod* instr) {
1499 DCHECK(instr->representation().IsSmiOrInteger32());
1500 DCHECK(instr->left()->representation().Equals(instr->representation()));
1501 DCHECK(instr->right()->representation().Equals(instr->representation()));
1502 LOperand* dividend = UseFixed(instr->left(), eax);
1503 LOperand* divisor = UseRegister(instr->right());
1507 if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1508 instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1515 LInstruction* LChunkBuilder::DoMod(HMod* instr) {
1516 if (instr->representation().IsSmiOrInteger32()) {
1517 if (instr->RightIsPowerOf2()) {
1518 return DoModByPowerOf2I(instr);
1519 } else if (instr->right()->IsConstant()) {
1520 return DoModByConstI(instr);
1522 return DoModI(instr);
1524 } else if (instr->representation().IsDouble()) {
1525 return DoArithmeticD(Token::MOD, instr);
1527 return DoArithmeticT(Token::MOD, instr);
1532 LInstruction* LChunkBuilder::DoMul(HMul* instr) {
1533 if (instr->representation().IsSmiOrInteger32()) {
1534 DCHECK(instr->left()->representation().Equals(instr->representation()));
1535 DCHECK(instr->right()->representation().Equals(instr->representation()));
1536 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
1537 LOperand* right = UseOrConstant(instr->BetterRightOperand());
1539 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1543 if (instr->CheckFlag(HValue::kCanOverflow) ||
1544 instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1548 } else if (instr->representation().IsDouble()) {
1549 return DoArithmeticD(Token::MUL, instr);
1551 return DoArithmeticT(Token::MUL, instr);
1556 LInstruction* LChunkBuilder::DoSub(HSub* instr) {
1557 if (instr->representation().IsSmiOrInteger32()) {
1558 DCHECK(instr->left()->representation().Equals(instr->representation()));
1559 DCHECK(instr->right()->representation().Equals(instr->representation()));
1560 LOperand* left = UseRegisterAtStart(instr->left());
1561 LOperand* right = UseOrConstantAtStart(instr->right());
1564 if (instr->CheckFlag(HValue::kCanOverflow)) {
1568 } else if (instr->representation().IsDouble()) {
1569 return DoArithmeticD(Token::SUB, instr);
1571 return DoArithmeticT(Token::SUB, instr);
1576 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
1577 if (instr->representation().IsSmiOrInteger32()) {
1578 DCHECK(instr->left()->representation().Equals(instr->representation()));
1579 DCHECK(instr->right()->representation().Equals(instr->representation()));
1584 bool use_lea = LAddI::UseLea(instr);
1585 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
1586 HValue* right_candidate = instr->BetterRightOperand();
1591 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow);
1599 } else if (instr->representation().IsDouble()) {
1600 return DoArithmeticD(Token::ADD, instr);
1601 } else if (instr->representation().IsExternal()) {
1602 DCHECK(instr->left()->representation().IsExternal());
1603 DCHECK(instr->right()->representation().IsInteger32());
1604 DCHECK(!instr->CheckFlag(HValue::kCanOverflow));
1605 bool use_lea = LAddI::UseLea(instr);
1606 LOperand* left = UseRegisterAtStart(instr->left());
1607 HValue* right_candidate = instr->right();
1617 return DoArithmeticT(Token::ADD, instr);
1622 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) {
1625 if (instr->representation().IsSmiOrInteger32()) {
1626 DCHECK(instr->left()->representation().Equals(instr->representation()));
1627 DCHECK(instr->right()->representation().Equals(instr->representation()));
1628 left = UseRegisterAtStart(instr->BetterLeftOperand());
1629 right = UseOrConstantAtStart(instr->BetterRightOperand());
1631 DCHECK(instr->representation().IsDouble());
1632 DCHECK(instr->left()->representation().IsDouble());
1633 DCHECK(instr->right()->representation().IsDouble());
1634 left = UseRegisterAtStart(instr->left());
1635 right = UseRegisterAtStart(instr->right());
1642 LInstruction* LChunkBuilder::DoPower(HPower* instr) {
1643 DCHECK(instr->representation().IsDouble());
1646 Representation exponent_type = instr->right()->representation();
1647 DCHECK(instr->left()->representation().IsDouble());
1648 LOperand* left = UseFixedDouble(instr->left(), xmm2);
1651 ? UseFixedDouble(instr->right(), xmm1)
1652 : UseFixed(instr->right(), MathPowTaggedDescriptor::exponent());
1654 return MarkAsCall(DefineFixedDouble(result, xmm3), instr,
1659 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
1660 DCHECK(instr->left()->representation().IsSmiOrTagged());
1661 DCHECK(instr->right()->representation().IsSmiOrTagged());
1662 LOperand* context = UseFixed(instr->context(), esi);
1663 LOperand* left = UseFixed(instr->left(), edx);
1664 LOperand* right = UseFixed(instr->right(), eax);
1666 return MarkAsCall(DefineFixed(result, eax), instr);
1671 HCompareNumericAndBranch* instr) {
1672 Representation r = instr->representation();
1674 DCHECK(instr->left()->representation().Equals(r));
1675 DCHECK(instr->right()->representation().Equals(r));
1676 LOperand* left = UseRegisterOrConstantAtStart(instr->left());
1677 LOperand* right = UseOrConstantAtStart(instr->right());
1681 DCHECK(instr->left()->representation().IsDouble());
1682 DCHECK(instr->right()->representation().IsDouble());
1685 if (CanBeImmediateConstant(instr->left()) &&
1686 CanBeImmediateConstant(instr->right())) {
1689 left = UseConstant(instr->left());
1690 right = UseConstant(instr->right());
1692 left = UseRegisterAtStart(instr->left());
1693 right = UseRegisterAtStart(instr->right());
1701 HCompareObjectEqAndBranch* instr) {
1702 LOperand* left = UseRegisterAtStart(instr->left());
1703 LOperand* right = UseOrConstantAtStart(instr->right());
1709 HCompareHoleAndBranch* instr) {
1710 LOperand* value = UseRegisterAtStart(instr->value());
1716 HCompareMinusZeroAndBranch* instr) {
1717 LOperand* value = UseRegister(instr->value());
1723 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) {
1724 DCHECK(instr->value()->representation().IsSmiOrTagged());
1726 return new(zone()) LIsObjectAndBranch(UseRegister(instr->value()), temp);
1730 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) {
1731 DCHECK(instr->value()->representation().IsTagged());
1733 return new(zone()) LIsStringAndBranch(UseRegister(instr->value()), temp);
1737 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) {
1738 DCHECK(instr->value()->representation().IsTagged());
1739 return new(zone()) LIsSmiAndBranch(Use(instr->value()));
1744 HIsUndetectableAndBranch* instr) {
1745 DCHECK(instr->value()->representation().IsTagged());
1747 UseRegisterAtStart(instr->value()), TempRegister());
1752 HStringCompareAndBranch* instr) {
1753 DCHECK(instr->left()->representation().IsTagged());
1754 DCHECK(instr->right()->representation().IsTagged());
1755 LOperand* context = UseFixed(instr->context(), esi);
1756 LOperand* left = UseFixed(instr->left(), edx);
1757 LOperand* right = UseFixed(instr->right(), eax);
1762 return MarkAsCall(result, instr);
1767 HHasInstanceTypeAndBranch* instr) {
1768 DCHECK(instr->value()->representation().IsTagged());
1770 UseRegisterAtStart(instr->value()),
1776 HGetCachedArrayIndex* instr) {
1777 DCHECK(instr->value()->representation().IsTagged());
1778 LOperand* value = UseRegisterAtStart(instr->value());
1785 HHasCachedArrayIndexAndBranch* instr) {
1786 DCHECK(instr->value()->representation().IsTagged());
1788 UseRegisterAtStart(instr->value()));
1793 HClassOfTestAndBranch* instr) {
1794 DCHECK(instr->value()->representation().IsTagged());
1795 return new(zone()) LClassOfTestAndBranch(UseRegister(instr->value()),
1801 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) {
1802 LOperand* map = UseRegisterAtStart(instr->value());
1807 LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
1808 LOperand* date = UseFixed(instr->value(), eax);
1810 new(zone()) LDateField(date, FixedTemp(ecx), instr->index());
1811 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY);
1815 LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) {
1816 LOperand* string = UseRegisterAtStart(instr->string());
1817 LOperand* index = UseRegisterOrConstantAtStart(instr->index());
1822 LOperand* LChunkBuilder::GetSeqStringSetCharOperand(HSeqStringSetChar* instr) {
1823 if (instr->encoding() == String::ONE_BYTE_ENCODING) {
1825 return UseFixed(instr->value(), eax);
1827 return UseFixedOrConstant(instr->value(), eax);
1831 return UseRegisterAtStart(instr->value());
1833 return UseRegisterOrConstantAtStart(instr->value());
1839 LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) {
1840 LOperand* string = UseRegisterAtStart(instr->string());
1842 ? UseRegisterAtStart(instr->index())
1843 : UseRegisterOrConstantAtStart(instr->index());
1844 LOperand* value = GetSeqStringSetCharOperand(instr);
1845 LOperand* context = FLAG_debug_code ? UseFixed(instr->context(), esi) : NULL;
1849 result = MarkAsCall(result, instr);
1855 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
1856 if (!FLAG_debug_code && instr->skip_check()) return NULL;
1857 LOperand* index = UseRegisterOrConstantAtStart(instr->index());
1859 ? UseOrConstantAtStart(instr->length())
1860 : UseAtStart(instr->length());
1862 if (!FLAG_debug_code || !instr->skip_check()) {
1870 HBoundsCheckBaseIndexInformation* instr) {
1876 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
1883 LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) {
1896 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1897 Representation from = instr->from();
1898 Representation to = instr->to();
1899 HValue* val = instr->value();
1928 bool truncating = instr->CanTruncateToInt32();
1950 bool truncating = instr->CanTruncateToInt32();
1963 if (!instr->CheckFlag(HValue::kCanOverflow)) {
1977 if (instr->CheckFlag(HValue::kCanOverflow)) {
1995 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
1996 LOperand* value = UseAtStart(instr->value());
1998 if (!instr->value()->type().IsHeapObject()) {
2005 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) {
2006 LOperand* value = UseRegisterAtStart(instr->value());
2011 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
2012 LOperand* value = UseRegisterAtStart(instr->value());
2019 LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) {
2024 LOperand* value = instr->object_in_new_space()
2025 ? UseRegisterAtStart(instr->value()) : UseAtStart(instr->value());
2030 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
2031 if (instr->IsStabilityCheck()) return new(zone()) LCheckMaps;
2032 LOperand* value = UseRegisterAtStart(instr->value());
2034 if (instr->HasMigrationTarget()) {
2042 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
2043 HValue* value = instr->value();
2063 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) {
2064 HValue* value = instr->value();
2070 LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) {
2071 LOperand* lo = UseRegister(instr->lo());
2072 LOperand* hi = UseRegister(instr->hi());
2077 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
2078 LOperand* context = info()->IsStub() ? UseFixed(instr->context(), esi) : NULL;
2079 LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count());
2081 UseFixed(instr->value(), eax), context, parameter_count);
2085 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
2086 Representation r = instr->representation();
2092 double value = instr->DoubleValue();
2107 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
2109 return instr->RequiresHoleCheck()
2115 LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
2116 LOperand* context = UseFixed(instr->context(), esi);
2118 UseFixed(instr->global_object(), LoadDescriptor::ReceiverRegister());
2126 return MarkAsCall(DefineFixed(result, eax), instr);
2130 LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
2132 new(zone()) LStoreGlobalCell(UseRegister(instr->value()));
2133 return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
2137 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
2138 LOperand* context = UseRegisterAtStart(instr->value());
2141 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
2148 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
2151 LOperand* context = UseRegister(instr->context());
2152 if (instr->NeedsWriteBarrier()) {
2153 value = UseTempRegister(instr->value());
2156 value = UseRegister(instr->value());
2160 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
2167 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
2168 LOperand* obj = (instr->access().IsExternalMemory() &&
2169 instr->access().offset() == 0)
2170 ? UseRegisterOrConstantAtStart(instr->object())
2171 : UseRegisterAtStart(instr->object());
2176 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
2177 LOperand* context = UseFixed(instr->context(), esi);
2179 UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
2186 return MarkAsCall(DefineFixed(result, eax), instr);
2191 HLoadFunctionPrototype* instr) {
2193 new(zone()) LLoadFunctionPrototype(UseRegister(instr->function()),
2198 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) {
2203 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
2204 DCHECK(instr->key()->representation().IsSmiOrInteger32());
2205 ElementsKind elements_kind = instr->elements_kind();
2207 instr->key()->representation(), elements_kind);
2209 ? UseTempRegister(instr->key())
2210 : UseRegisterOrConstantAtStart(instr->key());
2213 if (!instr->is_typed_elements()) {
2214 LOperand* obj = UseRegisterAtStart(instr->elements());
2218 (instr->representation().IsInteger32() &&
2219 !(IsDoubleOrFloatElementsKind(instr->elements_kind()))) ||
2220 (instr->representation().IsDouble() &&
2221 (IsDoubleOrFloatElementsKind(instr->elements_kind()))));
2222 LOperand* backing_store = UseRegister(instr->elements());
2226 if ((instr->is_external() || instr->is_fixed_typed_array()) ?
2228 ((instr->elements_kind() == EXTERNAL_UINT32_ELEMENTS ||
2229 instr->elements_kind() == UINT32_ELEMENTS) &&
2230 !instr->CheckFlag(HInstruction::kUint32)) :
2233 instr->RequiresHoleCheck()) {
2240 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
2241 LOperand* context = UseFixed(instr->context(), esi);
2243 UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
2244 LOperand* key = UseFixed(instr->key(), LoadDescriptor::NameRegister());
2251 return MarkAsCall(DefineFixed(result, eax), instr);
2255 LOperand* LChunkBuilder::GetStoreKeyedValueOperand(HStoreKeyed* instr) {
2256 ElementsKind elements_kind = instr->elements_kind();
2267 return UseFixed(instr->value(), eax);
2270 return UseRegister(instr->value());
2274 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
2275 if (!instr->is_typed_elements()) {
2276 DCHECK(instr->elements()->representation().IsTagged());
2277 DCHECK(instr->key()->representation().IsInteger32() ||
2278 instr->key()->representation().IsSmi());
2280 if (instr->value()->representation().IsDouble()) {
2281 LOperand* object = UseRegisterAtStart(instr->elements());
2283 val = UseRegisterAtStart(instr->value());
2284 LOperand* key = UseRegisterOrConstantAtStart(instr->key());
2287 DCHECK(instr->value()->representation().IsSmiOrTagged());
2288 bool needs_write_barrier = instr->NeedsWriteBarrier();
2290 LOperand* obj = UseRegister(instr->elements());
2294 val = UseTempRegister(instr->value());
2295 key = UseTempRegister(instr->key());
2297 val = UseRegisterOrConstantAtStart(instr->value());
2298 key = UseRegisterOrConstantAtStart(instr->key());
2304 ElementsKind elements_kind = instr->elements_kind();
2306 (instr->value()->representation().IsInteger32() &&
2308 (instr->value()->representation().IsDouble() &&
2310 DCHECK((instr->is_fixed_typed_array() &&
2311 instr->elements()->representation().IsTagged()) ||
2312 (instr->is_external() &&
2313 instr->elements()->representation().IsExternal()));
2315 LOperand* backing_store = UseRegister(instr->elements());
2316 LOperand* val = GetStoreKeyedValueOperand(instr);
2318 instr->key()->representation(), elements_kind);
2320 ? UseTempRegister(instr->key())
2321 : UseRegisterOrConstantAtStart(instr->key());
2326 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
2327 LOperand* context = UseFixed(instr->context(), esi);
2329 UseFixed(instr->object(), StoreDescriptor::ReceiverRegister());
2330 LOperand* key = UseFixed(instr->key(), StoreDescriptor::NameRegister());
2331 LOperand* value = UseFixed(instr->value(), StoreDescriptor::ValueRegister());
2333 DCHECK(instr->object()->representation().IsTagged());
2334 DCHECK(instr->key()->representation().IsTagged());
2335 DCHECK(instr->value()->representation().IsTagged());
2339 return MarkAsCall(result, instr);
2344 HTransitionElementsKind* instr) {
2345 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
2346 LOperand* object = UseRegister(instr->object());
2354 LOperand* object = UseFixed(instr->object(), eax);
2355 LOperand* context = UseFixed(instr->context(), esi);
2358 return MarkAsCall(result, instr);
2364 HTrapAllocationMemento* instr) {
2365 LOperand* object = UseRegister(instr->object());
2373 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
2374 bool is_in_object = instr->access().IsInobject();
2375 bool is_external_location = instr->access().IsExternalMemory() &&
2376 instr->access().offset() == 0;
2377 bool needs_write_barrier = instr->NeedsWriteBarrier();
2378 bool needs_write_barrier_for_map = instr->has_transition() &&
2379 instr->NeedsWriteBarrierForMap();
2384 ? UseRegister(instr->object())
2385 : UseTempRegister(instr->object());
2390 obj = UseRegisterOrConstant(instr->object());
2393 ? UseRegister(instr->object())
2394 : UseRegisterAtStart(instr->object());
2397 bool can_be_constant = instr->value()->IsConstant() &&
2398 HConstant::cast(instr->value())->NotInNewSpace() &&
2399 !instr->field_representation().IsDouble();
2402 if (instr->field_representation().IsInteger8() ||
2403 instr->field_representation().IsUInteger8()) {
2406 val = UseFixed(instr->value(), eax);
2408 val = UseTempRegister(instr->value());
2410 val = UseRegisterOrConstant(instr->value());
2411 } else if (instr->field_representation().IsDouble()) {
2412 val = UseRegisterAtStart(instr->value());
2414 val = UseRegister(instr->value());
2429 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
2430 LOperand* context = UseFixed(instr->context(), esi);
2432 UseFixed(instr->object(), StoreDescriptor::ReceiverRegister());
2433 LOperand* value = UseFixed(instr->value(), StoreDescriptor::ValueRegister());
2437 return MarkAsCall(result, instr);
2441 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) {
2442 LOperand* context = UseFixed(instr->context(), esi);
2443 LOperand* left = UseFixed(instr->left(), edx);
2444 LOperand* right = UseFixed(instr->right(), eax);
2446 return MarkAsCall(DefineFixed(string_add, eax), instr);
2450 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
2451 LOperand* string = UseTempRegister(instr->string());
2452 LOperand* index = UseTempRegister(instr->index());
2453 LOperand* context = UseAny(instr->context());
2460 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
2461 LOperand* char_code = UseRegister(instr->value());
2462 LOperand* context = UseAny(instr->context());
2469 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) {
2471 LOperand* context = UseAny(instr->context());
2472 LOperand* size = instr->size()->IsConstant()
2473 ? UseConstant(instr->size())
2474 : UseTempRegister(instr->size());
2481 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) {
2482 LOperand* context = UseFixed(instr->context(), esi);
2484 DefineFixed(new(zone()) LRegExpLiteral(context), eax), instr);
2488 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) {
2489 LOperand* context = UseFixed(instr->context(), esi);
2491 DefineFixed(new(zone()) LFunctionLiteral(context), eax), instr);
2495 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
2498 current_block_->last_environment()->set_ast_id(instr->ast_id());
2503 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
2505 if (instr->kind() == HParameter::STACK_PARAMETER) {
2506 int spill_index = chunk()->GetParameterStackSlot(instr->index());
2512 int index = static_cast<int>(instr->index());
2519 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
2522 int env_index = instr->index();
2524 if (instr->environment()->is_parameter_index(env_index)) {
2527 spill_index = env_index - instr->environment()->first_local_index();
2542 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) {
2543 LOperand* context = UseFixed(instr->context(), esi);
2545 return MarkAsCall(DefineFixed(result, eax), instr);
2549 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
2558 LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) {
2559 instr->ReplayEnvironment(current_block_->last_environment());
2566 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
2568 LOperand* args = UseRegister(instr->arguments());
2571 if (instr->length()->IsConstant() && instr->index()->IsConstant()) {
2572 length = UseRegisterOrConstant(instr->length());
2573 index = UseOrConstant(instr->index());
2575 length = UseTempRegister(instr->length());
2576 index = Use(instr->index());
2582 LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) {
2583 LOperand* object = UseFixed(instr->value(), eax);
2585 return MarkAsCall(DefineFixed(result, eax), instr);
2589 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
2590 LOperand* context = UseFixed(instr->context(), esi);
2591 LOperand* value = UseAtStart(instr->value());
2593 return MarkAsCall(DefineFixed(result, eax), instr);
2597 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
2598 return new(zone()) LTypeofIsAndBranch(UseTempRegister(instr->value()));
2603 HIsConstructCallAndBranch* instr) {
2608 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
2609 instr->ReplayEnvironment(current_block_->last_environment());
2614 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
2616 if (instr->is_function_entry()) {
2617 LOperand* context = UseFixed(instr->context(), esi);
2618 return MarkAsCall(new(zone()) LStackCheck(context), instr);
2620 DCHECK(instr->is_backwards_branch());
2621 LOperand* context = UseAny(instr->context());
2628 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
2630 outer->set_ast_id(instr->ReturnId());
2632 HEnvironment* inner = outer->CopyForInlining(instr->closure(),
2633 instr->arguments_count(),
2634 instr->function(),
2636 instr->inlining_kind());
2638 if (instr->arguments_var() != NULL && instr->arguments_object()->IsLinked()) {
2639 inner->Bind(instr->arguments_var(), instr->arguments_object());
2641 inner->BindContext(instr->closure_context());
2642 inner->set_entry(instr);
2644 chunk_->AddInlinedClosure(instr->closure());
2649 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
2657 DCHECK(instr->argument_delta() == -argument_count);
2667 LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) {
2668 LOperand* context = UseFixed(instr->context(), esi);
2669 LOperand* object = UseFixed(instr->enumerable(), eax);
2671 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY);
2675 LInstruction* LChunkBuilder::DoForInCacheArray(HForInCacheArray* instr) {
2676 LOperand* map = UseRegister(instr->map());
2682 LInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) {
2683 LOperand* value = UseRegisterAtStart(instr->value());
2684 LOperand* map = UseRegisterAtStart(instr->map());
2689 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
2690 LOperand* object = UseRegister(instr->object());
2691 LOperand* index = UseTempRegister(instr->index());
2698 LInstruction* LChunkBuilder::DoStoreFrameContext(HStoreFrameContext* instr) {
2699 LOperand* context = UseRegisterAtStart(instr->context());
2705 HAllocateBlockContext* instr) {
2706 LOperand* context = UseFixed(instr->context(), esi);
2707 LOperand* function = UseRegisterAtStart(instr->function());
2710 return MarkAsCall(DefineFixed(result, esi), instr);