Home | History | Annotate | Download | only in x87

Lines Matching refs:instr

575     HInstruction* instr = HInstruction::cast(value);
576 VisitInstruction(instr);
583 LInstruction* LChunkBuilder::Define(LTemplateResultInstruction<1>* instr,
586 instr->set_result(result);
587 return instr;
592 LTemplateResultInstruction<1>* instr) {
593 return Define(instr,
599 LTemplateResultInstruction<1>* instr,
601 return Define(instr,
607 LTemplateResultInstruction<1>* instr) {
608 return Define(instr,
613 LInstruction* LChunkBuilder::DefineFixed(LTemplateResultInstruction<1>* instr,
615 return Define(instr, ToUnallocated(reg));
619 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
623 instr->set_environment(CreateEnvironment(hydrogen_env,
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 ASSERT(!instr->HasPointerMap());
660 instr->set_pointer_map(new(zone()) LPointerMap(zone()));
661 return instr;
685 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) {
686 return new(zone()) LLabel(instr->block());
690 LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) {
691 return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value())));
695 LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) {
701 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
707 HBitwiseBinaryOperation* instr) {
708 if (instr->representation().IsSmiOrInteger32()) {
709 ASSERT(instr->left()->representation().Equals(instr->representation()));
710 ASSERT(instr->right()->representation().Equals(instr->representation()));
711 LOperand* left = UseRegisterAtStart(instr->left());
713 HValue* right_value = instr->right();
723 if (instr->representation().IsSmi() && constant_value > 0) {
724 does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToSmi);
734 does_deopt = !instr->CheckFlag(HInstruction::kUint32);
736 does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
744 return DoArithmeticT(op, instr);
750 HArithmeticBinaryOperation* instr) {
751 ASSERT(instr->representation().IsDouble());
752 ASSERT(instr->left()->representation().IsDouble());
753 ASSERT(instr->right()->representation().IsDouble());
755 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
756 LOperand* right = UseRegisterAtStart(instr->BetterRightOperand());
758 return MarkAsCall(DefineSameAsFirst(result), instr);
760 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
761 LOperand* right = UseRegisterAtStart(instr->BetterRightOperand());
769 HBinaryOperation* instr) {
770 HValue* left = instr->left();
771 HValue* right = instr->right();
774 LOperand* context = UseFixed(instr->context(), esi);
779 return MarkAsCall(DefineFixed(result, eax), instr);
854 LInstruction* instr = NULL;
857 instr = DefineAsRegister(new(zone()) LDummy());
860 instr = DefineAsRegister(new(zone())
875 instr = new(zone()) LGoto(successor);
877 instr = current->CompileToLithium(this);
884 if (instr != NULL) {
885 AddInstruction(instr, current);
892 void LChunkBuilder::AddInstruction(LInstruction* instr,
896 instr->set_hydrogen_value(hydrogen_val);
909 if (!(instr->ClobbersRegisters() &&
910 instr->ClobbersDoubleRegisters(isolate()))) {
913 for (UseIterator it(instr); !it.Done(); it.Advance()) {
917 if (instr->Output() != NULL) {
918 if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed;
920 for (TempIterator it(instr); !it.Done(); it.Advance()) {
928 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
929 instr = AssignPointerMap(instr);
931 if (FLAG_stress_environments && !instr->HasEnvironment()) {
932 instr = AssignEnvironment(instr);
934 if (instr->IsGoto() && LGoto::cast(instr)->jumps_to_join()) {
943 chunk_->AddInstruction(instr, current_block_);
945 if (instr->IsCall()) {
950 instruction_needing_environment = instr;
967 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
968 return new(zone()) LGoto(instr->FirstSuccessor());
972 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
973 HValue* value = instr->value();
976 ToBooleanStub::Types expected = instr->expected_input_types();
992 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) {
997 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) {
998 ASSERT(instr->value()->representation().IsTagged());
999 LOperand* value = UseRegisterAtStart(instr->value());
1016 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) {
1017 LOperand* left = UseFixed(instr->left(), InstanceofStub::left());
1018 LOperand* right = UseFixed(instr->right(), InstanceofStub::right());
1019 LOperand* context = UseFixed(instr->context(), esi);
1021 return MarkAsCall(DefineFixed(result, eax), instr);
1026 HInstanceOfKnownGlobal* instr) {
1029 UseFixed(instr->context(), esi),
1030 UseFixed(instr->left(), InstanceofStub::left()),
1032 return MarkAsCall(DefineFixed(result, eax), instr);
1036 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) {
1037 LOperand* receiver = UseRegister(instr->receiver());
1038 LOperand* function = UseRegister(instr->function());
1046 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
1047 LOperand* function = UseFixed(instr->function(), edi);
1048 LOperand* receiver = UseFixed(instr->receiver(), eax);
1049 LOperand* length = UseFixed(instr->length(), ebx);
1050 LOperand* elements = UseFixed(instr->elements(), ecx);
1055 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY);
1059 LInstruction* LChunkBuilder::DoPushArguments(HPushArguments* instr) {
1060 int argc = instr->OperandCount();
1062 LOperand* argument = UseAny(instr->argument(i));
1063 AddInstruction(new(zone()) LPushArgument(argument), instr);
1078 HInnerAllocatedObject* instr) {
1079 LOperand* base_object = UseRegisterAtStart(instr->base_object());
1080 LOperand* offset = UseRegisterOrConstantAtStart(instr->offset());
1086 LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) {
1087 return instr->HasNoUses()
1093 LInstruction* LChunkBuilder::DoContext(HContext* instr) {
1094 if (instr->HasNoUses()) return NULL;
1104 LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) {
1105 LOperand* context = UseFixed(instr->context(), esi);
1106 return MarkAsCall(new(zone()) LDeclareGlobals(context), instr);
1111 HCallJSFunction* instr) {
1112 LOperand* function = UseFixed(instr->function(), edi);
1116 return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
1121 HCallWithDescriptor* instr) {
1122 const CallInterfaceDescriptor* descriptor = instr->descriptor();
1124 LOperand* target = UseRegisterOrConstantAtStart(instr->target());
1125 ZoneList<LOperand*> ops(instr->OperandCount(), zone());
1127 for (int i = 1; i < instr->OperandCount(); i++) {
1128 LOperand* op = UseFixed(instr->OperandAt(i),
1135 return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
1139 LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
1140 LOperand* context = UseFixed(instr->context(), esi);
1141 LOperand* function = UseFixed(instr->function(), edi);
1143 return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
1147 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
1148 switch (instr->op()) {
1149 case kMathFloor: return DoMathFloor(instr);
1150 case kMathRound: return DoMathRound(instr);
1151 case kMathAbs: return DoMathAbs(instr);
1152 case kMathLog: return DoMathLog(instr);
1153 case kMathExp: return DoMathExp(instr);
1154 case kMathSqrt: return DoMathSqrt(instr);
1155 case kMathPowHalf: return DoMathPowHalf(instr);
1156 case kMathClz32: return DoMathClz32(instr);
1164 LInstruction* LChunkBuilder::DoMathFloor(HUnaryMathOperation* instr) {
1165 LOperand* input = UseRegisterAtStart(instr->value());
1171 LInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) {
1178 LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) {
1179 LOperand* context = UseAny(instr->context()); // Deferred use.
1180 LOperand* input = UseRegisterAtStart(instr->value());
1183 Representation r = instr->value()->representation();
1190 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) {
1191 ASSERT(instr->representation().IsDouble());
1192 ASSERT(instr->value()->representation().IsDouble());
1193 LOperand* input = UseRegisterAtStart(instr->value());
1194 return MarkAsCall(DefineSameAsFirst(new(zone()) LMathLog(input)), instr);
1198 LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) {
1199 LOperand* input = UseRegisterAtStart(instr->value());
1205 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) {
1206 ASSERT(instr->representation().IsDouble());
1207 ASSERT(instr->value()->representation().IsDouble());
1208 LOperand* value = UseTempRegister(instr->value());
1216 LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) {
1217 LOperand* input = UseRegisterAtStart(instr->value());
1223 LInstruction* LChunkBuilder::DoMathPowHalf(HUnaryMathOperation* instr) {
1224 LOperand* input = UseRegisterAtStart(instr->value());
1231 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) {
1232 LOperand* context = UseFixed(instr->context(), esi);
1233 LOperand* constructor = UseFixed(instr->constructor(), edi);
1235 return MarkAsCall(DefineFixed(result, eax), instr);
1239 LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) {
1240 LOperand* context = UseFixed(instr->context(), esi);
1241 LOperand* constructor = UseFixed(instr->constructor(), edi);
1243 return MarkAsCall(DefineFixed(result, eax), instr);
1247 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
1248 LOperand* context = UseFixed(instr->context(), esi);
1249 LOperand* function = UseFixed(instr->function(), edi);
1251 return MarkAsCall(DefineFixed(call, eax), instr);
1255 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) {
1256 LOperand* context = UseFixed(instr->context(), esi);
1257 return MarkAsCall(DefineFixed(new(zone()) LCallRuntime(context), eax), instr);
1261 LInstruction* LChunkBuilder::DoRor(HRor* instr) {
1262 return DoShift(Token::ROR, instr);
1266 LInstruction* LChunkBuilder::DoShr(HShr* instr) {
1267 return DoShift(Token::SHR, instr);
1271 LInstruction* LChunkBuilder::DoSar(HSar* instr) {
1272 return DoShift(Token::SAR, instr);
1276 LInstruction* LChunkBuilder::DoShl(HShl* instr) {
1277 return DoShift(Token::SHL, instr);
1281 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) {
1282 if (instr->representation().IsSmiOrInteger32()) {
1283 ASSERT(instr->left()->representation().Equals(instr->representation()));
1284 ASSERT(instr->right()->representation().Equals(instr->representation()));
1285 ASSERT(instr->CheckFlag(HValue::kTruncatingToInt32));
1287 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
1288 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand());
1291 return DoArithmeticT(instr->op(), instr);
1296 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) {
1297 ASSERT(instr->representation().IsSmiOrInteger32());
1298 ASSERT(instr->left()->representation().Equals(instr->representation()));
1299 ASSERT(instr->right()->representation().Equals(instr->representation()));
1300 LOperand* dividend = UseRegister(instr->left());
1301 int32_t divisor = instr->right()->GetInteger32Constant();
1304 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1305 (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) ||
1306 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
1314 LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) {
1315 ASSERT(instr->representation().IsInteger32());
1316 ASSERT(instr->left()->representation().Equals(instr->representation()));
1317 ASSERT(instr->right()->representation().Equals(instr->representation()));
1318 LOperand* dividend = UseRegister(instr->left());
1319 int32_t divisor = instr->right()->GetInteger32Constant();
1325 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1326 !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
1333 LInstruction* LChunkBuilder::DoDivI(HDiv* instr) {
1334 ASSERT(instr->representation().IsSmiOrInteger32());
1335 ASSERT(instr->left()->representation().Equals(instr->representation()));
1336 ASSERT(instr->right()->representation().Equals(instr->representation()));
1337 LOperand* dividend = UseFixed(instr->left(), eax);
1338 LOperand* divisor = UseRegister(instr->right());
1342 if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1343 instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
1344 instr->CheckFlag(HValue::kCanOverflow) ||
1345 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
1352 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
1353 if (instr->representation().IsSmiOrInteger32()) {
1354 if (instr->RightIsPowerOf2()) {
1355 return DoDivByPowerOf2I(instr);
1356 } else if (instr->right()->IsConstant()) {
1357 return DoDivByConstI(instr);
1359 return DoDivI(instr);
1361 } else if (instr->representation().IsDouble()) {
1362 return DoArithmeticD(Token::DIV, instr);
1364 return DoArithmeticT(Token::DIV, instr);
1369 LInstruction* LChunkBuilder::DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr) {
1370 LOperand* dividend = UseRegisterAtStart(instr->left());
1371 int32_t divisor = instr->right()->GetInteger32Constant();
1374 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1375 (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) {
1382 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) {
1383 ASSERT(instr->representation().IsInteger32());
1384 ASSERT(instr->left()->representation().Equals(instr->representation()));
1385 ASSERT(instr->right()->representation().Equals(instr->representation()));
1386 LOperand* dividend = UseRegister(instr->left());
1387 int32_t divisor = instr->right()->GetInteger32Constant();
1391 ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) ||
1392 (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ?
1402 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) {
1409 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* 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 = UseFixed(instr->left(), eax);
1414 LOperand* divisor = UseRegister(instr->right());
1418 if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1419 instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
1420 instr->CheckFlag(HValue::kCanOverflow)) {
1427 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
1428 if (instr->RightIsPowerOf2()) {
1429 return DoFlooringDivByPowerOf2I(instr);
1430 } else if (instr->right()->IsConstant()) {
1431 return DoFlooringDivByConstI(instr);
1433 return DoFlooringDivI(instr);
1438 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) {
1439 ASSERT(instr->representation().IsSmiOrInteger32());
1440 ASSERT(instr->left()->representation().Equals(instr->representation()));
1441 ASSERT(instr->right()->representation().Equals(instr->representation()));
1442 LOperand* dividend = UseRegisterAtStart(instr->left());
1443 int32_t divisor = instr->right()->GetInteger32Constant();
1446 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1453 LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) {
1454 ASSERT(instr->representation().IsSmiOrInteger32());
1455 ASSERT(instr->left()->representation().Equals(instr->representation()));
1456 ASSERT(instr->right()->representation().Equals(instr->representation()));
1457 LOperand* dividend = UseRegister(instr->left());
1458 int32_t divisor = instr->right()->GetInteger32Constant();
1463 if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1470 LInstruction* LChunkBuilder::DoModI(HMod* instr) {
1471 ASSERT(instr->representation().IsSmiOrInteger32());
1472 ASSERT(instr->left()->representation().Equals(instr->representation()));
1473 ASSERT(instr->right()->representation().Equals(instr->representation()));
1474 LOperand* dividend = UseFixed(instr->left(), eax);
1475 LOperand* divisor = UseRegister(instr->right());
1479 if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1480 instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1487 LInstruction* LChunkBuilder::DoMod(HMod* instr) {
1488 if (instr->representation().IsSmiOrInteger32()) {
1489 if (instr->RightIsPowerOf2()) {
1490 return DoModByPowerOf2I(instr);
1491 } else if (instr->right()->IsConstant()) {
1492 return DoModByConstI(instr);
1494 return DoModI(instr);
1496 } else if (instr->representation().IsDouble()) {
1497 return DoArithmeticD(Token::MOD, instr);
1499 return DoArithmeticT(Token::MOD, instr);
1504 LInstruction* LChunkBuilder::DoMul(HMul* instr) {
1505 if (instr->representation().IsSmiOrInteger32()) {
1506 ASSERT(instr->left()->representation().Equals(instr->representation()));
1507 ASSERT(instr->right()->representation().Equals(instr->representation()));
1508 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
1509 LOperand* right = UseOrConstant(instr->BetterRightOperand());
1511 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1515 if (instr->CheckFlag(HValue::kCanOverflow) ||
1516 instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1520 } else if (instr->representation().IsDouble()) {
1521 return DoArithmeticD(Token::MUL, instr);
1523 return DoArithmeticT(Token::MUL, instr);
1528 LInstruction* LChunkBuilder::DoSub(HSub* instr) {
1529 if (instr->representation().IsSmiOrInteger32()) {
1530 ASSERT(instr->left()->representation().Equals(instr->representation()));
1531 instr->right()->representation().Equals(instr->representation()));
1532 LOperand* left = UseRegisterAtStart(instr->left());
1533 LOperand* right = UseOrConstantAtStart(instr->right());
1536 if (instr->CheckFlag(HValue::kCanOverflow)) {
1540 } else if (instr->representation().IsDouble()) {
1541 return DoArithmeticD(Token::SUB, instr);
1543 return DoArithmeticT(Token::SUB, instr);
1548 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
1549 if (instr->representation().IsSmiOrInteger32()) {
1550 ASSERT(instr->left()->representation().Equals(instr->representation()));
1551 ASSERT(instr->right()->representation().Equals(instr->representation()));
1556 bool use_lea = LAddI::UseLea(instr);
1557 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
1558 HValue* right_candidate = instr->BetterRightOperand();
1563 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow);
1571 } else if (instr->representation().IsDouble()) {
1572 return DoArithmeticD(Token::ADD, instr);
1573 } else if (instr->representation().IsExternal()) {
1574 ASSERT(instr->left()->representation().IsExternal());
1575 ASSERT(instr->right()->representation().IsInteger32());
1576 ASSERT(!instr->CheckFlag(HValue::kCanOverflow));
1577 bool use_lea = LAddI::UseLea(instr);
1578 LOperand* left = UseRegisterAtStart(instr->left());
1579 HValue* right_candidate = instr->right();
1589 return DoArithmeticT(Token::ADD, instr);
1594 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) {
1597 if (instr->representation().IsSmiOrInteger32()) {
1598 ASSERT(instr->left()->representation().Equals(instr->representation()));
1599 ASSERT(instr->right()->representation().Equals(instr->representation()));
1600 left = UseRegisterAtStart(instr->BetterLeftOperand());
1601 right = UseOrConstantAtStart(instr->BetterRightOperand());
1603 ASSERT(instr->representation().IsDouble());
1604 ASSERT(instr->left()->representation().IsDouble());
1605 ASSERT(instr->right()->representation().IsDouble());
1606 left = UseRegisterAtStart(instr->left());
1607 right = UseRegisterAtStart(instr->right());
1614 LInstruction* LChunkBuilder::DoPower(HPower* instr) {
1621 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
1622 ASSERT(instr->left()->representation().IsSmiOrTagged());
1623 ASSERT(instr->right()->representation().IsSmiOrTagged());
1624 LOperand* context = UseFixed(instr->context(), esi);
1625 LOperand* left = UseFixed(instr->left(), edx);
1626 LOperand* right = UseFixed(instr->right(), eax);
1628 return MarkAsCall(DefineFixed(result, eax), instr);
1633 HCompareNumericAndBranch* instr) {
1634 Representation r = instr->representation();
1636 ASSERT(instr->left()->representation().Equals(r));
1637 ASSERT(instr->right()->representation().Equals(r));
1638 LOperand* left = UseRegisterOrConstantAtStart(instr->left());
1639 LOperand* right = UseOrConstantAtStart(instr->right());
1643 ASSERT(instr->left()->representation().IsDouble());
1644 ASSERT(instr->right()->representation().IsDouble());
1647 if (CanBeImmediateConstant(instr->left()) &&
1648 CanBeImmediateConstant(instr->right())) {
1651 left = UseConstant(instr->left());
1652 right = UseConstant(instr->right());
1654 left = UseRegisterAtStart(instr->left());
1655 right = UseRegisterAtStart(instr->right());
1663 HCompareObjectEqAndBranch* instr) {
1664 LOperand* left = UseRegisterAtStart(instr->left());
1665 LOperand* right = UseOrConstantAtStart(instr->right());
1671 HCompareHoleAndBranch* instr) {
1672 LOperand* value = UseRegisterAtStart(instr->value());
1678 HCompareMinusZeroAndBranch* instr) {
1679 LOperand* value = UseRegister(instr->value());
1685 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) {
1686 ASSERT(instr->value()->representation().IsSmiOrTagged());
1688 return new(zone()) LIsObjectAndBranch(UseRegister(instr->value()), temp);
1692 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) {
1693 ASSERT(instr->value()->representation().IsTagged());
1695 return new(zone()) LIsStringAndBranch(UseRegister(instr->value()), temp);
1699 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) {
1700 ASSERT(instr->value()->representation().IsTagged());
1701 return new(zone()) LIsSmiAndBranch(Use(instr->value()));
1706 HIsUndetectableAndBranch* instr) {
1707 ASSERT(instr->value()->representation().IsTagged());
1709 UseRegisterAtStart(instr->value()), TempRegister());
1714 HStringCompareAndBranch* instr) {
1715 ASSERT(instr->left()->representation().IsTagged());
1716 ASSERT(instr->right()->representation().IsTagged());
1717 LOperand* context = UseFixed(instr->context(), esi);
1718 LOperand* left = UseFixed(instr->left(), edx);
1719 LOperand* right = UseFixed(instr->right(), eax);
1724 return MarkAsCall(result, instr);
1729 HHasInstanceTypeAndBranch* instr) {
1730 ASSERT(instr->value()->representation().IsTagged());
1732 UseRegisterAtStart(instr->value()),
1738 HGetCachedArrayIndex* instr) {
1739 ASSERT(instr->value()->representation().IsTagged());
1740 LOperand* value = UseRegisterAtStart(instr->value());
1747 HHasCachedArrayIndexAndBranch* instr) {
1748 ASSERT(instr->value()->representation().IsTagged());
1750 UseRegisterAtStart(instr->value()));
1755 HClassOfTestAndBranch* instr) {
1756 ASSERT(instr->value()->representation().IsTagged());
1757 return new(zone()) LClassOfTestAndBranch(UseRegister(instr->value()),
1763 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) {
1764 LOperand* map = UseRegisterAtStart(instr->value());
1769 LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
1770 LOperand* date = UseFixed(instr->value(), eax);
1772 new(zone()) LDateField(date, FixedTemp(ecx), instr->index());
1773 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY);
1777 LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) {
1778 LOperand* string = UseRegisterAtStart(instr->string());
1779 LOperand* index = UseRegisterOrConstantAtStart(instr->index());
1784 LOperand* LChunkBuilder::GetSeqStringSetCharOperand(HSeqStringSetChar* instr) {
1785 if (instr->encoding() == String::ONE_BYTE_ENCODING) {
1787 return UseFixed(instr->value(), eax);
1789 return UseFixedOrConstant(instr->value(), eax);
1793 return UseRegisterAtStart(instr->value());
1795 return UseRegisterOrConstantAtStart(instr->value());
1801 LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) {
1802 LOperand* string = UseRegisterAtStart(instr->string());
1804 ? UseRegisterAtStart(instr->index())
1805 : UseRegisterOrConstantAtStart(instr->index());
1806 LOperand* value = GetSeqStringSetCharOperand(instr);
1807 LOperand* context = FLAG_debug_code ? UseFixed(instr->context(), esi) : NULL;
1811 result = MarkAsCall(result, instr);
1817 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
1818 if (!FLAG_debug_code && instr->skip_check()) return NULL;
1819 LOperand* index = UseRegisterOrConstantAtStart(instr->index());
1821 ? UseOrConstantAtStart(instr->length())
1822 : UseAtStart(instr->length());
1824 if (!FLAG_debug_code || !instr->skip_check()) {
1832 HBoundsCheckBaseIndexInformation* instr) {
1838 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
1845 LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) {
1858 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1859 Representation from = instr->from();
1860 Representation to = instr->to();
1861 HValue* val = instr->value();
1909 bool truncating = instr->CanTruncateToInt32();
1918 if (!instr->CheckFlag(HValue::kCanOverflow)) {
1935 if (instr->CheckFlag(HValue::kCanOverflow)) {
1953 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
1954 LOperand* value = UseAtStart(instr->value());
1956 if (!instr->value()->type().IsHeapObject()) {
1963 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) {
1964 LOperand* value = UseRegisterAtStart(instr->value());
1969 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
1970 LOperand* value = UseRegisterAtStart(instr->value());
1977 LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) {
1982 LOperand* value = instr->object_in_new_space()
1983 ? UseRegisterAtStart(instr->value()) : UseAtStart(instr->value());
1988 instr) {
1989 if (instr->IsStabilityCheck()) return new(zone()) LCheckMaps;
1990 LOperand* value = UseRegisterAtStart(instr->value());
1992 if (instr->HasMigrationTarget()) {
2000 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
2001 HValue* value = instr->value();
2011 LOperand* value = UseRegister(instr->value());
2020 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) {
2021 HValue* value = instr->value();
2027 LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) {
2028 LOperand* lo = UseRegister(instr->lo());
2029 LOperand* hi = UseRegister(instr->hi());
2034 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
2035 LOperand* context = info()->IsStub() ? UseFixed(instr->context(), esi) : NULL;
2036 LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count());
2038 UseFixed(instr->value(), eax), context, parameter_count);
2042 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
2043 Representation r = instr->representation();
2049 double value = instr->DoubleValue();
2064 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
2066 return instr->RequiresHoleCheck()
2072 LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
2073 LOperand* context = UseFixed(instr->context(), esi);
2074 LOperand* global_object = UseFixed(instr->global_object(), edx);
2077 return MarkAsCall(DefineFixed(result, eax), instr);
2081 LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
2083 new(zone()) LStoreGlobalCell(UseRegister(instr->value()));
2084 return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
2088 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
2089 LOperand* context = UseRegisterAtStart(instr->value());
2092 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
2099 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
2102 LOperand* context = UseRegister(instr->context());
2103 if (instr->NeedsWriteBarrier()) {
2104 value = UseTempRegister(instr->value());
2107 value = UseRegister(instr->value());
2111 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
2118 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
2119 LOperand* obj = (instr->access().IsExternalMemory() &&
2120 instr->access().offset() == 0)
2121 ? UseRegisterOrConstantAtStart(instr->object())
2122 : UseRegisterAtStart(instr->object());
2127 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
2128 LOperand* context = UseFixed(instr->context(), esi);
2129 LOperand* object = UseFixed(instr->object(), edx);
2131 return MarkAsCall(DefineFixed(result, eax), instr);
2136 HLoadFunctionPrototype* instr) {
2138 new(zone()) LLoadFunctionPrototype(UseRegister(instr->function()),
2143 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) {
2148 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
2149 ASSERT(instr->key()->representation().IsSmiOrInteger32());
2150 ElementsKind elements_kind = instr->elements_kind();
2152 instr->key()->representation(), elements_kind);
2154 ? UseTempRegister(instr->key())
2155 : UseRegisterOrConstantAtStart(instr->key());
2158 if (!instr->is_typed_elements()) {
2159 LOperand* obj = UseRegisterAtStart(instr->elements());
2163 (instr->representation().IsInteger32() &&
2164 !(IsDoubleOrFloatElementsKind(instr->elements_kind()))) ||
2165 (instr->representation().IsDouble() &&
2166 (IsDoubleOrFloatElementsKind(instr->elements_kind()))));
2167 LOperand* backing_store = UseRegister(instr->elements());
2171 if ((instr->is_external() || instr->is_fixed_typed_array()) ?
2173 ((instr->elements_kind() == EXTERNAL_UINT32_ELEMENTS ||
2174 instr->elements_kind() == UINT32_ELEMENTS) &&
2175 !instr->CheckFlag(HInstruction::kUint32)) :
2178 instr->RequiresHoleCheck()) {
2185 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
2186 LOperand* context = UseFixed(instr->context(), esi);
2187 LOperand* object = UseFixed(instr->object(), edx);
2188 LOperand* key = UseFixed(instr->key(), ecx);
2192 return MarkAsCall(DefineFixed(result, eax), instr);
2196 LOperand* LChunkBuilder::GetStoreKeyedValueOperand(HStoreKeyed* instr) {
2197 ElementsKind elements_kind = instr->elements_kind();
2208 return UseFixed(instr->value(), eax);
2212 return UseRegisterAtStart(instr->value());
2215 return UseRegister(instr->value());
2219 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
2220 if (!instr->is_typed_elements()) {
2221 ASSERT(instr->elements()->representation().IsTagged());
2222 ASSERT(instr->key()->representation().IsInteger32() ||
2223 instr->key()->representation().IsSmi());
2225 if (instr->value()->representation().IsDouble()) {
2226 LOperand* object = UseRegisterAtStart(instr->elements());
2228 val = UseRegisterAtStart(instr->value());
2229 LOperand* key = UseRegisterOrConstantAtStart(instr->key());
2232 ASSERT(instr->value()->representation().IsSmiOrTagged());
2233 bool needs_write_barrier = instr->NeedsWriteBarrier();
2235 LOperand* obj = UseRegister(instr->elements());
2239 val = UseTempRegister(instr->value());
2240 key = UseTempRegister(instr->key());
2242 val = UseRegisterOrConstantAtStart(instr->value());
2243 key = UseRegisterOrConstantAtStart(instr->key());
2249 ElementsKind elements_kind = instr->elements_kind();
2251 (instr->value()->representation().IsInteger32() &&
2253 (instr->value()->representation().IsDouble() &&
2255 ASSERT((instr->is_fixed_typed_array() &&
2256 instr->elements()->representation().IsTagged()) ||
2257 (instr->is_external() &&
2258 instr->elements()->representation().IsExternal()));
2260 LOperand* backing_store = UseRegister(instr->elements());
2261 LOperand* val = GetStoreKeyedValueOperand(instr);
2263 instr->key()->representation(), elements_kind);
2265 ? UseTempRegister(instr->key())
2266 : UseRegisterOrConstantAtStart(instr->key());
2271 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
2272 LOperand* context = UseFixed(instr->context(), esi);
2273 LOperand* object = UseFixed(instr->object(), edx);
2274 LOperand* key = UseFixed(instr->key(), ecx);
2275 LOperand* value = UseFixed(instr->value(), eax);
2277 ASSERT(instr->object()->representation().IsTagged());
2278 ASSERT(instr->key()->representation().IsTagged());
2279 ASSERT(instr->value()->representation().IsTagged());
2283 return MarkAsCall(result, instr);
2288 HTransitionElementsKind* instr) {
2289 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
2290 LOperand* object = UseRegister(instr->object());
2298 LOperand* object = UseFixed(instr->object(), eax);
2299 LOperand* context = UseFixed(instr->context(), esi);
2302 return MarkAsCall(result, instr);
2308 HTrapAllocationMemento* instr) {
2309 LOperand* object = UseRegister(instr->object());
2317 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
2318 bool is_in_object = instr->access().IsInobject();
2319 bool is_external_location = instr->access().IsExternalMemory() &&
2320 instr->access().offset() == 0;
2321 bool needs_write_barrier = instr->NeedsWriteBarrier();
2322 bool needs_write_barrier_for_map = instr->has_transition() &&
2323 instr->NeedsWriteBarrierForMap();
2328 ? UseRegister(instr->object())
2329 : UseTempRegister(instr->object());
2334 obj = UseRegisterOrConstant(instr->object());
2337 ? UseRegister(instr->object())
2338 : UseRegisterAtStart(instr->object());
2341 bool can_be_constant = instr->value()->IsConstant() &&
2342 HConstant::cast(instr->value())->NotInNewSpace() &&
2343 !instr->field_representation().IsDouble();
2346 if (instr->field_representation().IsInteger8() ||
2347 instr->field_representation().IsUInteger8()) {
2350 val = UseFixed(instr->value(), eax);
2352 val = UseTempRegister(instr->value());
2354 val = UseRegisterOrConstant(instr->value());
2355 } else if (instr->field_representation().IsSmi()) {
2356 val = UseTempRegister(instr->value());
2357 } else if (instr->field_representation().IsDouble()) {
2358 val = UseRegisterAtStart(instr->value());
2360 val = UseRegister(instr->value());
2375 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
2376 LOperand* context = UseFixed(instr->context(), esi);
2377 LOperand* object = UseFixed(instr->object(), edx);
2378 LOperand* value = UseFixed(instr->value(), eax);
2382 return MarkAsCall(result, instr);
2386 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) {
2387 LOperand* context = UseFixed(instr->context(), esi);
2388 LOperand* left = UseFixed(instr->left(), edx);
2389 LOperand* right = UseFixed(instr->right(), eax);
2391 return MarkAsCall(DefineFixed(string_add, eax), instr);
2395 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
2396 LOperand* string = UseTempRegister(instr->string());
2397 LOperand* index = UseTempRegister(instr->index());
2398 LOperand* context = UseAny(instr->context());
2405 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
2406 LOperand* char_code = UseRegister(instr->value());
2407 LOperand* context = UseAny(instr->context());
2414 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) {
2416 LOperand* context = UseAny(instr->context());
2417 LOperand* size = instr->size()->IsConstant()
2418 ? UseConstant(instr->size())
2419 : UseTempRegister(instr->size());
2426 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) {
2427 LOperand* context = UseFixed(instr->context(), esi);
2429 DefineFixed(new(zone()) LRegExpLiteral(context), eax), instr);
2433 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) {
2434 LOperand* context = UseFixed(instr->context(), esi);
2436 DefineFixed(new(zone()) LFunctionLiteral(context), eax), instr);
2440 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
2443 instr->ast_id());
2448 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
2450 if (instr->kind() == HParameter::STACK_PARAMETER) {
2451 int spill_index = chunk()->GetParameterStackSlot(instr->index());
2457 int index = static_cast<int>(instr->index());
2464 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
2467 int env_index = instr->index();
2469 if (instr->environment()->is_parameter_index(env_index)) {
2472 spill_index = env_index - instr->environment()->first_local_index();
2487 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) {
2488 LOperand* context = UseFixed(instr->context(), esi);
2490 return MarkAsCall(DefineFixed(result, eax), instr);
2494 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
2503 LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) {
2504 instr->ReplayEnvironment(current_block_->last_environment());
2511 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
2513 LOperand* args = UseRegister(instr->arguments());
2516 if (instr->length()->IsConstant() && instr->index()->IsConstant()) {
2517 length = UseRegisterOrConstant(instr->length());
2518 index = UseOrConstant(instr->index());
2520 length = UseTempRegister(instr->length());
2521 index = Use(instr->index());
2527 LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) {
2528 LOperand* object = UseFixed(instr->value(), eax);
2530 return MarkAsCall(DefineFixed(result, eax), instr);
2534 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
2535 LOperand* context = UseFixed(instr->context(), esi);
2536 LOperand* value = UseAtStart(instr->value());
2538 return MarkAsCall(DefineFixed(result, eax), instr);
2542 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
2543 return new(zone()) LTypeofIsAndBranch(UseTempRegister(instr->value()));
2548 HIsConstructCallAndBranch* instr) {
2553 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
2554 instr->ReplayEnvironment(current_block_->last_environment());
2559 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
2561 if (instr->is_function_entry()) {
2562 LOperand* context = UseFixed(instr->context(), esi);
2563 return MarkAsCall(new(zone()) LStackCheck(context), instr);
2565 ASSERT(instr->is_backwards_branch());
2566 LOperand* context = UseAny(instr->context());
2573 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
2575 outer->set_ast_id(instr->ReturnId());
2577 HEnvironment* inner = outer->CopyForInlining(instr->closure(),
2578 instr->arguments_count(),
2579 instr->function(),
2581 instr->inlining_kind());
2583 if (instr->arguments_var() != NULL && instr->arguments_object()->IsLinked()) {
2584 inner->Bind(instr->arguments_var(), instr->arguments_object());
2586 inner->set_entry(instr);
2588 chunk_->AddInlinedClosure(instr->closure());
2593 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
2601 ASSERT(instr->argument_delta() == -argument_count);
2611 LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) {
2612 LOperand* context = UseFixed(instr->context(), esi);
2613 LOperand* object = UseFixed(instr->enumerable(), eax);
2615 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY);
2619 LInstruction* LChunkBuilder::DoForInCacheArray(HForInCacheArray* instr) {
2620 LOperand* map = UseRegister(instr->map());
2626 LInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) {
2627 LOperand* value = UseRegisterAtStart(instr->value());
2628 LOperand* map = UseRegisterAtStart(instr->map());
2633 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
2634 LOperand* object = UseRegister(instr->object());
2635 LOperand* index = UseTempRegister(instr->index());
2642 LInstruction* LChunkBuilder::DoStoreFrameContext(HStoreFrameContext* instr) {
2643 LOperand* context = UseRegisterAtStart(instr->context());
2649 HAllocateBlockContext* instr) {
2650 LOperand* context = UseFixed(instr->context(), esi);
2651 LOperand* function = UseRegisterAtStart(instr->function());
2654 return MarkAsCall(DefineFixed(result, esi), instr);