Home | History | Annotate | Download | only in arm64

Lines Matching refs:instr

377     HInstruction* instr = HInstruction::cast(value);
378 VisitInstruction(instr);
435 LInstruction* LChunkBuilder::Define(LTemplateResultInstruction<1>* instr,
438 instr->set_result(result);
439 return instr;
444 LTemplateResultInstruction<1>* instr) {
445 return Define(instr,
451 LTemplateResultInstruction<1>* instr, int index) {
452 return Define(instr,
458 LTemplateResultInstruction<1>* instr) {
459 return Define(instr,
465 LTemplateResultInstruction<1>* instr, Register reg) {
466 return Define(instr, ToUnallocated(reg));
471 LTemplateResultInstruction<1>* instr, DoubleRegister reg) {
472 return Define(instr, ToUnallocated(reg));
476 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
481 instr->VerifyCall();
483 instr->MarkAsCall();
484 instr = AssignPointerMap(instr);
493 if (needs_environment && !instr->HasEnvironment()) {
494 instr = AssignEnvironment(instr);
496 instr->environment()->set_has_been_used();
499 return instr;
503 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) {
504 ASSERT(!instr->HasPointerMap());
505 instr->set_pointer_map(new(zone()) LPointerMap(zone()));
506 return instr;
658 LInstruction* instr = NULL;
661 instr = DefineAsRegister(new(zone()) LDummy());
664 instr = DefineAsRegister(new(zone())
679 instr = new(zone()) LGoto(successor);
681 instr = current->CompileToLithium(this);
688 if (instr != NULL) {
689 AddInstruction(instr, current);
696 void LChunkBuilder::AddInstruction(LInstruction* instr,
700 instr->set_hydrogen_value(hydrogen_val);
713 if (!(instr->ClobbersRegisters() &&
714 instr->ClobbersDoubleRegisters(isolate()))) {
717 for (UseIterator it(instr); !it.Done(); it.Advance()) {
721 if (instr->Output() != NULL) {
722 if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed;
724 for (TempIterator it(instr); !it.Done(); it.Advance()) {
732 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
733 instr = AssignPointerMap(instr);
735 if (FLAG_stress_environments && !instr->HasEnvironment()) {
736 instr = AssignEnvironment(instr);
738 chunk_->AddInstruction(instr, current_block_);
740 if (instr->IsCall()) {
745 instruction_needing_environment = instr;
762 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
766 instr->set_environment(CreateEnvironment(hydrogen_env,
769 return instr;
773 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
781 HArithmeticBinaryOperation* instr) {
782 ASSERT(instr->representation().IsDouble());
783 ASSERT(instr->left()->representation().IsDouble());
784 ASSERT(instr->right()->representation().IsDouble());
787 LOperand* left = UseFixedDouble(instr->left(), d0);
788 LOperand* right = UseFixedDouble(instr->right(), d1);
790 return MarkAsCall(DefineFixedDouble(result, d0), instr);
792 LOperand* left = UseRegisterAtStart(instr->left());
793 LOperand* right = UseRegisterAtStart(instr->right());
801 HBinaryOperation* instr) {
807 HValue* left = instr->left();
808 HValue* right = instr->right();
812 ASSERT(instr->representation().IsSmiOrTagged());
816 LOperand* context = UseFixed(instr->context(), cp);
821 return MarkAsCall(DefineFixed(result, x0), instr);
826 HBoundsCheckBaseIndexInformation* instr) {
832 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
838 if (instr->length()->IsConstant() && instr->index()->IsConstant()) {
839 args = UseRegisterAtStart(instr->arguments());
840 length = UseConstant(instr->length());
841 index = UseConstant(instr->index());
843 args = UseRegister(instr->arguments());
844 length = UseRegisterAtStart(instr->length());
845 index = UseRegisterOrConstantAtStart(instr->index());
852 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
853 if (instr->representation().IsSmiOrInteger32()) {
854 ASSERT(instr->left()->representation().Equals(instr->representation()));
855 ASSERT(instr->right()->representation().Equals(instr->representation()));
857 LInstruction* shifted_operation = TryDoOpWithShiftedRightOperand(instr);
862 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
864 UseRegisterOrConstantAtStart(instr->BetterRightOperand());
865 LInstruction* result = instr->representation().IsSmi() ?
868 if (instr->CheckFlag(HValue::kCanOverflow)) {
872 } else if (instr->representation().IsExternal()) {
873 ASSERT(instr->left()->representation().IsExternal());
874 ASSERT(instr->right()->representation().IsInteger32());
875 ASSERT(!instr->CheckFlag(HValue::kCanOverflow));
876 LOperand* left = UseRegisterAtStart(instr->left());
877 LOperand* right = UseRegisterOrConstantAtStart(instr->right());
879 } else if (instr->representation().IsDouble()) {
880 return DoArithmeticD(Token::ADD, instr);
882 ASSERT(instr->representation().IsTagged());
883 return DoArithmeticT(Token::ADD, instr);
888 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) {
890 LOperand* context = UseAny(instr->context());
891 LOperand* size = UseRegisterOrConstant(instr->size());
894 LOperand* temp3 = instr->MustPrefillWithFiller() ? TempRegister() : NULL;
900 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
901 LOperand* function = UseFixed(instr->function(), x1);
902 LOperand* receiver = UseFixed(instr->receiver(), x0);
903 LOperand* length = UseFixed(instr->length(), x2);
904 LOperand* elements = UseFixed(instr->elements(), x3);
909 return MarkAsCall(DefineFixed(result, x0), instr, CAN_DEOPTIMIZE_EAGERLY);
913 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* instr) {
915 LOperand* temp = instr->from_inlined() ? NULL : TempRegister();
920 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* instr) {
922 LOperand* value = UseRegisterAtStart(instr->value());
927 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
936 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) {
937 if (instr->representation().IsSmiOrInteger32()) {
938 ASSERT(instr->left()->representation().Equals(instr->representation()));
939 ASSERT(instr->right()->representation().Equals(instr->representation()));
940 ASSERT(instr->CheckFlag(HValue::kTruncatingToInt32));
942 LInstruction* shifted_operation = TryDoOpWithShiftedRightOperand(instr);
947 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
949 UseRegisterOrConstantAtStart(instr->BetterRightOperand());
950 return instr->representation().IsSmi() ?
954 return DoArithmeticT(instr->op(), instr);
959 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) {
963 return new(zone()) LLabel(instr->block());
967 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
968 if (!FLAG_debug_code && instr->skip_check()) return NULL;
969 LOperand* index = UseRegisterOrConstantAtStart(instr->index());
971 ? UseRegisterOrConstantAtStart(instr->length())
972 : UseRegisterAtStart(instr->length());
974 if (!FLAG_debug_code || !instr->skip_check()) {
981 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
982 HValue* value = instr->value();
1002 ToBooleanStub::Types expected = instr->expected_input_types();
1021 HCallJSFunction* instr) {
1022 LOperand* function = UseFixed(instr->function(), x1);
1026 return MarkAsCall(DefineFixed(result, x0), instr);
1031 HCallWithDescriptor* instr) {
1032 const CallInterfaceDescriptor* descriptor = instr->descriptor();
1034 LOperand* target = UseRegisterOrConstantAtStart(instr
1035 ZoneList<LOperand*> ops(instr->OperandCount(), zone());
1037 for (int i = 1; i < instr->OperandCount(); i++) {
1038 LOperand* op = UseFixed(instr->OperandAt(i),
1046 return MarkAsCall(DefineFixed(result, x0), instr);
1050 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
1051 LOperand* context = UseFixed(instr->context(), cp);
1052 LOperand* function = UseFixed(instr->function(), x1);
1054 return MarkAsCall(DefineFixed(call, x0), instr);
1058 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) {
1059 LOperand* context = UseFixed(instr->context(), cp);
1061 LOperand* constructor = UseFixed(instr->constructor(), x1);
1063 return MarkAsCall(DefineFixed(result, x0), instr);
1067 LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) {
1068 LOperand* context = UseFixed(instr->context(), cp);
1070 LOperand* constructor = UseFixed(instr->constructor(), x1);
1072 return MarkAsCall(DefineFixed(result, x0), instr);
1076 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) {
1077 LOperand* context = UseFixed(instr->context(), cp);
1078 return MarkAsCall(DefineFixed(new(zone()) LCallRuntime(context), x0), instr);
1082 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) {
1083 LOperand* context = UseFixed(instr->context(), cp);
1084 return MarkAsCall(DefineFixed(new(zone()) LCallStub(context), x0), instr);
1088 LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) {
1089 instr->ReplayEnvironment(current_block_->last_environment());
1096 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1097 Representation from = instr->from();
1098 Representation to = instr->to();
1099 HValue* val = instr->value();
1129 LOperand* temp2 = instr->CanTruncateToInt32()
1147 if (instr->CanTruncateToInt32()) {
1193 LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) {
1194 LOperand* value = UseRegisterAtStart(instr->value());
1199 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
1200 LOperand* value = UseRegisterAtStart(instr->value());
1207 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
1208 if (instr->IsStabilityCheck()) return new(zone()) LCheckMaps;
1209 LOperand* value = UseRegisterAtStart(instr->value());
1212 if (instr->HasMigrationTarget()) {
1220 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
1221 LOperand* value = UseRegisterAtStart(instr->value());
1223 if (!instr->value()->type().IsHeapObject()) {
1230 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) {
1231 LOperand* value = UseRegisterAtStart(instr->value());
1236 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
1237 HValue* value = instr->value();
1255 HClassOfTestAndBranch* instr) {
1256 ASSERT(instr->value()->representation().IsTagged());
1257 LOperand* value = UseRegisterAtStart(instr->value());
1265 HCompareNumericAndBranch* instr) {
1266 Representation r = instr->representation();
1268 ASSERT(instr->left()->representation().Equals(r));
1269 ASSERT(instr->right()->representation().Equals(r));
1270 LOperand* left = UseRegisterOrConstantAtStart(instr->left());
1271 LOperand* right = UseRegisterOrConstantAtStart(instr->right());
1275 ASSERT(instr->left()->representation().IsDouble());
1276 ASSERT(instr->right()->representation().IsDouble());
1284 LOperand* left = UseRegisterOrConstantAtStart(instr->left());
1285 LOperand* right = UseRegisterOrConstantAtStart(instr->right());
1291 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
1292 ASSERT(instr->left()->representation().IsTagged());
1293 ASSERT(instr->right()->representation().IsTagged());
1294 LOperand* context = UseFixed(instr->context(), cp);
1295 LOperand* left = UseFixed(instr->left(), x1);
1296 LOperand* right = UseFixed(instr->right(), x0);
1298 return MarkAsCall(DefineFixed(result, x0), instr);
1303 HCompareHoleAndBranch* instr) {
1304 LOperand* value = UseRegister(instr->value());
1305 if (instr->representation().IsTagged()) {
1315 HCompareObjectEqAndBranch* instr) {
1316 LOperand* left = UseRegisterAtStart(instr->left());
1317 LOperand* right = UseRegisterAtStart(instr->right());
1322 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) {
1323 ASSERT(instr->value()->representation().IsTagged());
1324 LOperand* value = UseRegisterAtStart(instr->value());
1330 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
1331 Representation r = instr->representation();
1349 LInstruction* LChunkBuilder::DoContext(HContext* instr) {
1350 if (instr->HasNoUses()) return NULL;
1360 LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
1361 LOperand* object = UseFixed(instr->value(), x0);
1362 LDateField* result = new(zone()) LDateField(object, instr->index());
1363 return MarkAsCall(DefineFixed(result, x0), instr, CAN_DEOPTIMIZE_EAGERLY);
1367 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) {
1372 LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) {
1373 LOperand* context = UseFixed(instr->context(), cp);
1374 return MarkAsCall(new(zone()) LDeclareGlobals(context), instr);
1378 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
1383 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) {
1384 ASSERT(instr->representation().IsInteger32());
1385 ASSERT(instr->left()->representation().Equals(instr->representation()));
1386 ASSERT(instr->right()->representation().Equals(instr->representation()));
1387 LOperand* dividend = UseRegister(instr->left());
1388 int32_t divisor = instr->right()->GetInteger32Constant();
1391 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1392 (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) ||
1393 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
1401 LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) {
1402 ASSERT(instr->representation().IsInteger32());
1403 ASSERT(instr->left()->representation().Equals(instr->representation()));
1404 ASSERT(instr->right()->representation().Equals(instr->representation()));
1405 LOperand* dividend = UseRegister(instr->left());
1406 int32_t divisor = instr->right()->GetInteger32Constant();
1407 LOperand* temp = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)
1412 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1413 !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
1420 LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) {
1421 ASSERT(instr->representation().IsSmiOrInteger32());
1422 ASSERT(instr->left()->representation().Equals(instr->representation()));
1423 ASSERT(instr->right()->representation().Equals(instr->representation()));
1424 LOperand* dividend = UseRegister(instr->left());
1425 LOperand* divisor = UseRegister(instr->right());
1426 LOperand* temp = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)
1430 if (!instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
1437 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
1438 if (instr->representation().IsSmiOrInteger32()) {
1439 if (instr->RightIsPowerOf2()) {
1440 return DoDivByPowerOf2I(instr);
1441 } else if (instr->right()->IsConstant()) {
1442 return DoDivByConstI(instr);
1444 return DoDivI(instr);
1446 } else if (instr->representation().IsDouble()) {
1447 return DoArithmeticD(Token::DIV, instr);
1449 return DoArithmeticT(Token::DIV, instr);
1454 LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) {
1455 return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value())));
1459 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
1461 outer->set_ast_id(instr->ReturnId());
1463 HEnvironment* inner = outer->CopyForInlining(instr->closure(),
1464 instr->arguments_count(),
1465 instr->function(),
1467 instr->inlining_kind());
1469 if ((instr->arguments_var() != NULL) &&
1470 instr->arguments_object()->IsLinked()) {
1471 inner->Bind(instr->arguments_var(), instr->arguments_object());
1473 inner->set_entry(instr);
1475 chunk_->AddInlinedClosure(instr->closure());
1480 LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) {
1487 HForceRepresentation* instr) {
1495 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) {
1496 LOperand* context = UseFixed(instr->context(), cp);
1498 DefineFixed(new(zone()) LFunctionLiteral(context), x0), instr);
1503 HGetCachedArrayIndex* instr) {
1504 ASSERT(instr->value()->representation().IsTagged());
1505 LOperand* value = UseRegisterAtStart(instr->value());
1510 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
1511 return new(zone()) LGoto(instr->FirstSuccessor());
1516 HHasCachedArrayIndexAndBranch* instr) {
1517 ASSERT(instr->value()->representation().IsTagged());
1519 UseRegisterAtStart(instr->value()), TempRegister());
1524 HHasInstanceTypeAndBranch* instr) {
1525 ASSERT(instr->value()->representation().IsTagged());
1526 LOperand* value = UseRegisterAtStart(instr->value());
1532 HInnerAllocatedObject* instr) {
1533 LOperand* base_object = UseRegisterAtStart(instr->base_object());
1534 LOperand* offset = UseRegisterOrConstantAtStart(instr->offset());
1540 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) {
1541 LOperand* context = UseFixed(instr->context(), cp);
1544 UseFixed(instr->left(), InstanceofStub::left()),
1545 UseFixed(instr->right(), InstanceofStub::right()));
1546 return MarkAsCall(DefineFixed(result, x0), instr);
1551 HInstanceOfKnownGlobal* instr) {
1553 UseFixed(instr->context(), cp),
1554 UseFixed(instr->left(), InstanceofStub::left()));
1555 return MarkAsCall(DefineFixed(result, x0), instr);
1559 LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
1560 LOperand* context = UseFixed(instr->context(), cp);
1562 LOperand* function = UseFixed(instr->function(), x1);
1564 return MarkAsCall(DefineFixed(result, x0), instr, CANNOT_DEOPTIMIZE_EAGERLY);
1569 HIsConstructCallAndBranch* instr) {
1575 HCompareMinusZeroAndBranch* instr) {
1576 LOperand* value = UseRegister(instr->value());
1582 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) {
1583 ASSERT(instr->value()->representation().IsTagged());
1584 LOperand* value = UseRegisterAtStart(instr->value());
1591 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) {
1592 ASSERT(instr->value()->representation().IsTagged());
1593 LOperand* value = UseRegisterAtStart(instr->value());
1599 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) {
1600 ASSERT(instr->value()->representation().IsTagged());
1601 return new(zone()) LIsSmiAndBranch(UseRegisterAtStart(instr->value()));
1606 HIsUndetectableAndBranch* instr) {
1607 ASSERT(instr->value()->representation().IsTagged());
1608 LOperand* value = UseRegisterAtStart(instr->value());
1613 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
1620 ASSERT(instr->argument_delta() == -argument_count);
1631 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
1632 LOperand* context = UseRegisterAtStart(instr->value());
1635 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
1643 HLoadFunctionPrototype* instr) {
1644 LOperand* function = UseRegister(instr->function());
1651 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
1653 return instr->RequiresHoleCheck()
1659 LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
1660 LOperand* context = UseFixed(instr->context(), cp);
1661 LOperand* global_object = UseFixed(instr->global_object(), x0);
1664 return MarkAsCall(DefineFixed(result, x0), instr);
1668 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
1669 ASSERT(instr->key()->representation().IsSmiOrInteger32());
1670 ElementsKind elements_kind = instr->elements_kind();
1671 LOperand* elements = UseRegister(instr->elements());
1672 LOperand* key = UseRegisterOrConstant(instr->key());
1674 if (!instr->is_typed_elements()) {
1675 if (instr->representation().IsDouble()) {
1676 LOperand* temp = (!instr->key()->IsConstant() ||
1677 instr->RequiresHoleCheck())
1683 return instr->RequiresHoleCheck()
1687 ASSERT(instr->representation().IsSmiOrTagged() ||
1688 instr->representation().IsInteger32());
1689 LOperand* temp = instr->key()->IsConstant() ? NULL : TempRegister();
1692 return instr->RequiresHoleCheck()
1697 ASSERT((instr->representation().IsInteger32() &&
1698 !IsDoubleOrFloatElementsKind(instr->elements_kind())) ||
1699 (instr->representation().IsDouble() &&
1700 IsDoubleOrFloatElementsKind(instr->elements_kind())));
1702 LOperand* temp = instr->key()->IsConstant() ? NULL : TempRegister();
1707 !instr->CheckFlag(HInstruction::kUint32)) {
1715 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
1716 LOperand* context = UseFixed(instr->context(), cp);
1717 LOperand* object = UseFixed(instr->object(), x1);
1718 LOperand* key = UseFixed(instr->key(), x0);
1722 return MarkAsCall(result, instr);
1726 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
1727 LOperand* object = UseRegisterAtStart(instr->object());
1732 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
1733 LOperand* context = UseFixed(instr->context(), cp);
1734 LOperand* object = UseFixed(instr->object(), x0);
1737 return MarkAsCall(result, instr);
1741 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) {
1746 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) {
1747 LOperand* map = UseRegisterAtStart(instr->value());
1752 LInstruction* LChunkBuilder::DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr) {
1753 ASSERT(instr->representation().IsInteger32());
1754 ASSERT(instr->left()->representation().Equals(instr->representation()));
1755 ASSERT(instr->right()->representation().Equals(instr->representation()));
1756 LOperand* dividend = UseRegisterAtStart(instr->left());
1757 int32_t divisor = instr->right()->GetInteger32Constant();
1760 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1761 (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) {
1768 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) {
1769 ASSERT(instr->representation().IsInteger32());
1770 ASSERT(instr->left()->representation().Equals(instr->representation()));
1771 ASSERT(instr->right()->representation().Equals(instr->representation()));
1772 LOperand* dividend = UseRegister(instr->left());
1773 int32_t divisor = instr->right()->GetInteger32Constant();
1775 ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) ||
1776 (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ?
1781 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) {
1788 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) {
1789 LOperand* dividend = UseRegister(instr->left());
1790 LOperand* divisor = UseRegister(instr->right());
1798 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
1799 if (instr->RightIsPowerOf2()) {
1800 return DoFlooringDivByPowerOf2I(instr);
1801 } else if (instr->right()->IsConstant()) {
1802 return DoFlooringDivByConstI(instr);
1804 return DoFlooringDivI(instr);
1809 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) {
1812 if (instr->representation().IsSmiOrInteger32()) {
1813 ASSERT(instr->left()->representation().Equals(instr->representation()));
1814 ASSERT(instr->right()->representation().Equals(instr->representation()));
1815 left = UseRegisterAtStart(instr->BetterLeftOperand());
1816 right = UseRegisterOrConstantAtStart(instr->BetterRightOperand());
1818 ASSERT(instr->representation().IsDouble());
1819 ASSERT(instr->left()->representation().IsDouble());
1820 ASSERT(instr->right()->representation().IsDouble());
1821 left = UseRegisterAtStart(instr->left());
1822 right = UseRegisterAtStart(instr->right());
1828 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) {
1829 ASSERT(instr->representation().IsInteger32());
1830 ASSERT(instr->left()->representation().Equals(instr->representation()));
1831 ASSERT(instr->right()->representation().Equals(instr->representation()));
1832 LOperand* dividend = UseRegisterAtStart(instr->left());
1833 int32_t divisor = instr->right()->GetInteger32Constant();
1836 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1843 LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) {
1844 ASSERT(instr->representation().IsInteger32());
1845 ASSERT(instr->left()->representation().Equals(instr->representation()));
1846 ASSERT(instr->right()->representation().Equals(instr->representation()));
1847 LOperand* dividend = UseRegister(instr->left());
1848 int32_t divisor = instr->right()->GetInteger32Constant();
1852 if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1859 LInstruction* LChunkBuilder::DoModI(HMod* instr) {
1860 ASSERT(instr->representation().IsSmiOrInteger32());
1861 ASSERT(instr->left()->representation().Equals(instr->representation()));
1862 ASSERT(instr->right()->representation().Equals(instr->representation()));
1863 LOperand* dividend = UseRegister(instr->left());
1864 LOperand* divisor = UseRegister(instr->right());
1866 if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1867 instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1874 LInstruction* LChunkBuilder::DoMod(HMod* instr) {
1875 if (instr->representation().IsSmiOrInteger32()) {
1876 if (instr->RightIsPowerOf2()) {
1877 return DoModByPowerOf2I(instr);
1878 } else if (instr->right()->IsConstant()) {
1879 return DoModByConstI(instr);
1881 return DoModI(instr);
1883 } else if (instr->representation().IsDouble()) {
1884 return DoArithmeticD(Token::MOD, instr);
1886 return DoArithmeticT(Token::MOD, instr);
1891 LInstruction* LChunkBuilder::DoMul(HMul* instr) {
1892 if (instr->representation().IsSmiOrInteger32()) {
1893 ASSERT(instr->left()->representation().Equals(instr->representation()));
1894 ASSERT(instr->right()->representation().Equals(instr->representation()));
1896 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow);
1897 bool bailout_on_minus_zero = instr->CheckFlag(HValue::kBailoutOnMinusZero);
1899 HValue* least_const = instr->BetterLeftOperand();
1900 HValue* most_const = instr->BetterRightOperand();
1936 LInstruction* result = instr->representation().IsSmi()
1943 } else if (instr->representation().IsDouble()) {
1944 return DoArithmeticD(Token::MUL, instr);
1946 return DoArithmeticT(Token::MUL, instr);
1951 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
1954 current_block_->last_environment()->set_ast_id(instr->ast_id());
1959 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
1961 if (instr->kind() == HParameter::STACK_PARAMETER) {
1962 int spill_index = chunk_->GetParameterStackSlot(instr->index());
1968 int index = static_cast<int>(instr->index());
1975 LInstruction* LChunkBuilder::DoPower(HPower* instr) {
1976 ASSERT(instr->representation().IsDouble());
1979 Representation exponent_type = instr->right()->representation();
1980 ASSERT(instr->left()->representation().IsDouble());
1981 LOperand* left = UseFixedDouble(instr->left(), d0);
1983 ? UseFixed(instr->right(), x12)
1985 ? UseFixedDouble(instr->right(), d1)
1986 : UseFixed(instr->right(), x11);
1989 instr,
1994 LInstruction* LChunkBuilder::DoPushArguments(HPushArguments* instr) {
1995 int argc = instr->OperandCount();
1996 AddInstruction(new(zone()) LPreparePushArguments(argc), instr);
2002 AddInstruction(push_args, instr);
2005 push_args->AddArgument(UseRegister(instr->argument(i)));
2012 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) {
2013 LOperand* context = UseFixed(instr->context(), cp);
2015 DefineFixed(new(zone()) LRegExpLiteral(context), x0), instr);
2019 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) {
2020 HValue* value = instr->value();
2026 LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) {
2027 LOperand* lo = UseRegisterAndClobber(instr->lo());
2028 LOperand* hi = UseRegister(instr->hi());
2033 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
2035 ? UseFixed(instr->context(), cp)
2037 LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count());
2038 return new(zone()) LReturn(UseFixed(instr->value(), x0), context,
2043 LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) {
2044 LOperand* string = UseRegisterAtStart(instr->string());
2045 LOperand* index = UseRegisterOrConstantAtStart(instr->index());
2053 LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) {
2054 LOperand* string = UseRegister(instr->string());
2056 ? UseRegister(instr->index())
2057 : UseRegisterOrConstant(instr->index());
2058 LOperand* value = UseRegister(instr->value());
2059 LOperand* context = FLAG_debug_code ? UseFixed(instr->context(), cp) : NULL;
2135 HBinaryOperation* instr) {
2137 HBitwiseBinaryOperation* shift = CanTransformToShiftedOp(instr, &left);
2140 return DoShiftedBinaryOp(instr, left, shift);
2179 HBitwiseBinaryOperation* instr) {
2180 if (instr->representation().IsTagged()) {
2181 return DoArithmeticT(op, instr);
2184 ASSERT(instr->representation().IsInteger32() ||
2185 instr->representation().IsSmi());
2186 ASSERT(instr->left()->representation().Equals(instr->representation()));
2187 ASSERT(instr->right()->representation().Equals(instr->representation()));
2189 if (ShiftCanBeOptimizedAway(instr)) {
2193 LOperand* left = instr->representation().IsSmi()
2194 ? UseRegister(instr->left())
2195 : UseRegisterAtStart(instr->left());
2197 HValue* right_value = instr->right();
2216 does_deopt = !instr->CheckFlag(HInstruction::kUint32);
2218 does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
2223 if (instr->representation().IsInteger32()) {
2226 ASSERT(instr->representation().IsSmi());
2235 LInstruction* LChunkBuilder::DoRor(HRor* instr) {
2236 return DoShift(Token::ROR, instr);
2240 LInstruction* LChunkBuilder::DoSar(HSar* instr) {
2241 return DoShift(Token::SAR, instr);
2245 LInstruction* LChunkBuilder::DoShl(HShl* instr) {
2246 return DoShift(Token::SHL, instr);
2250 LInstruction* LChunkBuilder::DoShr(HShr* instr) {
2251 return DoShift(Token::SHR, instr);
2255 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
2256 instr->ReplayEnvironment(current_block_->last_environment());
2261 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
2262 if (instr->is_function_entry()) {
2263 LOperand* context = UseFixed(instr->context(), cp);
2264 return MarkAsCall(new(zone()) LStackCheck(context), instr);
2266 ASSERT(instr->is_backwards_branch());
2267 LOperand* context = UseAny(instr->context());
2274 LInstruction* LChunkBuilder::DoStoreCodeEntry(HStoreCodeEntry* instr) {
2275 LOperand* function = UseRegister(instr->function());
2276 LOperand* code_object = UseRegisterAtStart(instr->code_object());
2282 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
2286 if (instr->NeedsWriteBarrier()) {
2289 context = UseRegisterAndClobber(instr->context());
2290 value = UseRegisterAndClobber(instr->value());
2292 context = UseRegister(instr->context());
2293 value = UseRegister(instr->value());
2296 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
2303 LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
2304 LOperand* value = UseRegister(instr->value());
2305 if (instr->RequiresHoleCheck()) {
2315 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
2316 LOperand* key = UseRegisterOrConstant(instr->key());
2321 if (!instr->is_typed_elements() &&
2322 instr->value()->representation().IsTagged() &&
2323 instr->NeedsWriteBarrier()) {
2325 elements = UseRegisterAndClobber(instr->elements());
2326 val = UseRegisterAndClobber(instr->value());
2329 elements = UseRegister(instr->elements());
2330 val = UseRegister(instr->value());
2331 temp = instr->key()->IsConstant() ? NULL : TempRegister();
2334 if (instr->is_typed_elements()) {
2335 ASSERT((instr->value()->representation().IsInteger32() &&
2336 !IsDoubleOrFloatElementsKind(instr->elements_kind())) ||
2337 (instr->value()->representation().IsDouble() &&
2338 IsDoubleOrFloatElementsKind(instr->elements_kind())));
2339 ASSERT((instr->is_fixed_typed_array() &&
2340 instr->elements()->representation().IsTagged()) ||
2341 (instr->is_external() &&
2342 instr->elements()->representation().IsExternal()));
2345 } else if (instr->value()->representation().IsDouble()) {
2346 ASSERT(instr->elements()->representation().IsTagged());
2350 ASSERT(instr->elements()->representation().IsTagged());
2351 ASSERT(instr->value()->representation().IsSmiOrTagged() ||
2352 instr->value()->representation().IsInteger32());
2358 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
2359 LOperand* context = UseFixed(instr->context(), cp);
2360 LOperand* object = UseFixed(instr->object(), x2);
2361 LOperand* key = UseFixed(instr->key(), x1);
2362 LOperand* value = UseFixed(instr->value(), x0);
2364 ASSERT(instr->object()->representation().IsTagged());
2365 ASSERT(instr->key()->representation().IsTagged());
2366 ASSERT(instr->value()->representation().IsTagged());
2369 new(zone()) LStoreKeyedGeneric(context, object, key, value), instr);
2373 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
2377 LOperand* object = UseRegister(instr->object());
2382 if (instr->access().IsExternalMemory() ||
2383 instr->field_representation().IsDouble()) {
2384 value = UseRegister(instr->value());
2385 } else if (instr->NeedsWriteBarrier()) {
2386 value = UseRegisterAndClobber(instr->value());
2389 } else if (instr->NeedsWriteBarrierForMap()) {
2390 value = UseRegister(instr->value());
2394 value = UseRegister(instr->value());
2402 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
2403 LOperand* context = UseFixed(instr->context(), cp);
2404 LOperand* object = UseFixed(instr->object(), x1);
2405 LOperand* value = UseFixed(instr->value(), x0);
2407 return MarkAsCall(result, instr);
2411 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) {
2412 LOperand* context = UseFixed(instr->context(), cp);
2413 LOperand* left = UseFixed(instr->left(), x1);
2414 LOperand* right = UseFixed(instr->right(), x0);
2417 return MarkAsCall(DefineFixed(result, x0), instr);
2421 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
2422 LOperand* string = UseRegisterAndClobber(instr->string());
2423 LOperand* index = UseRegisterAndClobber(instr->index());
2424 LOperand* context = UseAny(instr->context());
2431 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
2432 LOperand* char_code = UseRegister(instr->value());
2433 LOperand* context = UseAny(instr->context());
2441 HStringCompareAndBranch* instr) {
2442 ASSERT(instr->left()->representation().IsTagged());
2443 ASSERT(instr->right()->representation().IsTagged());
2444 LOperand* context = UseFixed(instr->context(), cp);
2445 LOperand* left = UseFixed(instr->left(), x1);
2446 LOperand* right = UseFixed(instr->right(), x0);
2449 return MarkAsCall(result, instr);
2453 LInstruction* LChunkBuilder::DoSub(HSub* instr) {
2454 if (instr->representation().IsSmiOrInteger32()) {
2455 ASSERT(instr->left()->representation().Equals(instr->representation()));
2456 ASSERT(instr->right()->representation().Equals(instr->representation()));
2458 LInstruction* shifted_operation = TryDoOpWithShiftedRightOperand(instr);
2464 if (instr->left()->IsConstant() &&
2465 (HConstant::cast(instr->left())->Integer32Value() == 0)) {
2466 left = UseConstant(instr->left());
2468 left = UseRegisterAtStart(instr->left());
2470 LOperand* right = UseRegisterOrConstantAtStart(instr->right());
2471 LInstruction* result = instr->representation().IsSmi() ?
2474 if (instr->CheckFlag(HValue::kCanOverflow)) {
2478 } else if (instr->representation().IsDouble()) {
2479 return DoArithmeticD(Token::SUB, instr);
2481 return DoArithmeticT(Token::SUB, instr);
2486 LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) {
2487 if (instr->HasNoUses()) {
2495 LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) {
2496 LOperand* object = UseFixed(instr->value(), x0);
2498 return MarkAsCall(DefineFixed(result, x0), instr);
2503 HTransitionElementsKind* instr) {
2504 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
2505 LOperand* object = UseRegister(instr->object());
2511 LOperand* object = UseFixed(instr->object(), x0);
2512 LOperand* context = UseFixed(instr->context(), cp);
2515 return MarkAsCall(result, instr);
2521 HTrapAllocationMemento* instr) {
2522 LOperand* object = UseRegister(instr->object());
2531 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
2532 LOperand* context = UseFixed(instr->context(), cp);
2538 new(zone()) LTypeof(context, UseRegisterAtStart(instr->value()));
2539 return MarkAsCall(DefineFixed(result, x0), instr);
2543 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
2545 // instr->type_literal() handle to test that here.
2550 UseRegister(instr->value()), temp1, temp2);
2554 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
2555 switch (instr->op()) {
2557 Representation r = instr->representation();
2561 LOperand* context = UseFixed(instr->context(), cp);
2562 LOperand* input = UseRegister(instr->value());
2570 LOperand* input = UseRegisterAtStart(instr->value());
2577 ASSERT(instr->representation().IsDouble());
2578 ASSERT(instr->value()->representation().IsDouble());
2579 LOperand* input = UseRegister(instr->value());
2589 ASSERT(instr->value()->representation().IsDouble());
2590 LOperand* input = UseRegisterAtStart(instr->value());
2591 if (instr->representation().IsInteger32()) {
2595 ASSERT(instr->representation().IsDouble());
2601 ASSERT(instr->representation().IsDouble());
2602 ASSERT(instr->value()->representation().IsDouble());
2603 LOperand* input = UseFixedDouble(instr->value(), d0);
2605 return MarkAsCall(DefineFixedDouble(result, d0), instr);
2608 ASSERT(instr->representation().IsDouble());
2609 ASSERT(instr->value()->representation().IsDouble());
2610 LOperand* input = UseRegister(instr->value());
2614 ASSERT(instr->value()->representation().IsDouble());
2615 LOperand* input = UseRegister(instr->value());
2616 if (instr->representation().IsInteger32()) {
2621 ASSERT(instr->representation().IsDouble());
2627 ASSERT(instr->representation().IsDouble());
2628 ASSERT(instr->value()->representation().IsDouble());
2629 LOperand* input = UseRegisterAtStart(instr->value());
2633 ASSERT(instr->representation().IsInteger32());
2634 ASSERT(instr->value()->representation().IsInteger32());
2635 LOperand* input = UseRegisterAtStart(instr->value());
2645 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
2648 int env_index = instr->index();
2650 if (instr->environment()->is_parameter_index(env_index)) {
2653 spill_index = env_index - instr->environment()->first_local_index();
2663 LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) {
2668 LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) {
2669 LOperand* context = UseFixed(instr->context(), cp);
2672 LOperand* object = UseFixed(instr->enumerable(), x0);
2674 return MarkAsCall(DefineFixed(result, x0), instr, CAN_DEOPTIMIZE_EAGERLY);
2678 LInstruction* LChunkBuilder::DoForInCacheArray(HForInCacheArray* instr) {
2679 LOperand* map = UseRegister(instr->map());
2684 LInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) {
2685 LOperand* value = UseRegisterAtStart(instr->value());
2686 LOperand* map = UseRegister(instr->map());
2692 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
2693 LOperand* object = UseRegisterAtStart(instr->object());
2694 LOperand* index = UseRegisterAndClobber(instr->index());
2701 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) {
2702 LOperand* receiver = UseRegister(instr->receiver());
2703 LOperand* function = UseRegister(instr->function());
2709 LInstruction* LChunkBuilder::DoStoreFrameContext(HStoreFrameContext* instr) {
2710 LOperand* context = UseRegisterAtStart(instr->context());
2716 HAllocateBlockContext* instr) {
2717 LOperand* context = UseFixed(instr->context(), cp);
2718 LOperand* function = UseRegisterAtStart(instr->function());
2721 return MarkAsCall(DefineFixed(result, cp), instr);