Home | History | Annotate | Download | only in ia32

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));
620 LTemplateResultInstruction<1>* instr,
622 return Define(instr, ToUnallocated(reg));
626 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
630 instr->set_environment(CreateEnvironment(hydrogen_env,
633 return instr;
637 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
643 instr->VerifyCall();
645 instr->MarkAsCall();
646 instr = AssignPointerMap(instr);
655 if (needs_environment && !instr->HasEnvironment()) {
656 instr = AssignEnvironment(instr);
658 instr->environment()->set_has_been_used();
661 return instr;
665 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) {
666 ASSERT(!instr->HasPointerMap());
667 instr->set_pointer_map(new(zone()) LPointerMap(zone()));
668 return instr;
699 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) {
700 return new(zone()) LLabel(instr->block());
704 LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) {
705 return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value())));
709 LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) {
715 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
721 HBitwiseBinaryOperation* instr) {
722 if (instr->representation().IsSmiOrInteger32()) {
723 ASSERT(instr->left()->representation().Equals(instr->representation()));
724 ASSERT(instr->right()->representation().Equals(instr->representation()));
725 LOperand* left = UseRegisterAtStart(instr->left());
727 HValue* right_value = instr->right();
737 if (instr->representation().IsSmi() && constant_value > 0) {
738 does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToSmi);
748 does_deopt = !instr->CheckFlag(HInstruction::kUint32);
750 does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
758 return DoArithmeticT(op, instr);
764 HArithmeticBinaryOperation* instr) {
765 ASSERT(instr->representation().IsDouble());
766 ASSERT(instr->left()->representation().IsDouble());
767 ASSERT(instr->right()->representation().IsDouble());
769 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
770 LOperand* right = UseRegisterAtStart(instr->BetterRightOperand());
772 return MarkAsCall(DefineSameAsFirst(result), instr);
774 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
775 LOperand* right = UseRegisterAtStart(instr->BetterRightOperand());
783 HBinaryOperation* instr) {
784 HValue* left = instr->left();
785 HValue* right = instr->right();
788 LOperand* context = UseFixed(instr->context(), esi);
793 return MarkAsCall(DefineFixed(result, eax), instr);
868 LInstruction* instr = NULL;
871 instr = DefineAsRegister(new(zone()) LDummy());
874 instr = DefineAsRegister(new(zone())
889 instr = new(zone()) LGoto(successor);
891 instr = current->CompileToLithium(this);
898 if (instr != NULL) {
899 AddInstruction(instr, current);
906 void LChunkBuilder::AddInstruction(LInstruction* instr,
910 instr->set_hydrogen_value(hydrogen_val);
923 if (!(instr->ClobbersRegisters() &&
924 instr->ClobbersDoubleRegisters(isolate()))) {
927 for (UseIterator it(instr); !it.Done(); it.Advance()) {
931 if (instr->Output() != NULL) {
932 if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed;
934 for (TempIterator it(instr); !it.Done(); it.Advance()) {
942 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
943 instr = AssignPointerMap(instr);
945 if (FLAG_stress_environments && !instr->HasEnvironment()) {
946 instr = AssignEnvironment(instr);
948 chunk_->AddInstruction(instr, current_block_);
950 if (instr->IsCall()) {
955 instruction_needing_environment = instr;
972 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
973 return new(zone()) LGoto(instr->FirstSuccessor());
977 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
978 HValue* value = instr->value();
981 ToBooleanStub::Types expected = instr->expected_input_types();
997 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) {
1002 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) {
1003 ASSERT(instr->value()->representation().IsTagged());
1004 LOperand* value = UseRegisterAtStart(instr->value());
1021 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) {
1022 LOperand* left = UseFixed(instr->left(), InstanceofStub::left());
1023 LOperand* right = UseFixed(instr->right(), InstanceofStub::right());
1024 LOperand* context = UseFixed(instr->context(), esi);
1026 return MarkAsCall(DefineFixed(result, eax), instr);
1031 HInstanceOfKnownGlobal* instr) {
1034 UseFixed(instr->context(), esi),
1035 UseFixed(instr->left(), InstanceofStub::left()),
1037 return MarkAsCall(DefineFixed(result, eax), instr);
1041 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) {
1042 LOperand* receiver = UseRegister(instr->receiver());
1043 LOperand* function = UseRegister(instr->function());
1051 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
1052 LOperand* function = UseFixed(instr->function(), edi);
1053 LOperand* receiver = UseFixed(instr->receiver(), eax);
1054 LOperand* length = UseFixed(instr->length(), ebx);
1055 LOperand* elements = UseFixed(instr->elements(), ecx);
1060 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY);
1064 LInstruction* LChunkBuilder::DoPushArguments(HPushArguments* instr) {
1065 int argc = instr->OperandCount();
1067 LOperand* argument = UseAny(instr->argument(i));
1068 AddInstruction(new(zone()) LPushArgument(argument), instr);
1083 HInnerAllocatedObject* instr) {
1084 LOperand* base_object = UseRegisterAtStart(instr->base_object());
1085 LOperand* offset = UseRegisterOrConstantAtStart(instr->offset());
1091 LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) {
1092 return instr->HasNoUses()
1098 LInstruction* LChunkBuilder::DoContext(HContext* instr) {
1099 if (instr->HasNoUses()) return NULL;
1109 LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) {
1110 LOperand* context = UseFixed(instr->context(), esi);
1111 return MarkAsCall(new(zone()) LDeclareGlobals(context), instr);
1116 HCallJSFunction* instr) {
1117 LOperand* function = UseFixed(instr->function(), edi);
1121 return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
1126 HCallWithDescriptor* instr) {
1127 const CallInterfaceDescriptor* descriptor = instr->descriptor();
1129 LOperand* target = UseRegisterOrConstantAtStart(instr->target());
1130 ZoneList<LOperand*> ops(instr->OperandCount(), zone());
1132 for (int i = 1; i < instr->OperandCount(); i++) {
1133 LOperand* op = UseFixed(instr->OperandAt(i),
1140 return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
1144 LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
1145 LOperand* context = UseFixed(instr->context(), esi);
1146 LOperand* function = UseFixed(instr->function(), edi);
1148 return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
1152 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
1153 switch (instr->op()) {
1154 case kMathFloor: return DoMathFloor(instr);
1155 case kMathRound: return DoMathRound(instr);
1156 case kMathAbs: return DoMathAbs(instr);
1157 case kMathLog: return DoMathLog(instr);
1158 case kMathExp: return DoMathExp(instr);
1159 case kMathSqrt: return DoMathSqrt(instr);
1160 case kMathPowHalf: return DoMathPowHalf(instr);
1161 case kMathClz32: return DoMathClz32(instr);
1169 LInstruction* LChunkBuilder::DoMathFloor(HUnaryMathOperation* instr) {
1170 LOperand* input = UseRegisterAtStart(instr->value());
1176 LInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) {
1177 LOperand* input = UseRegister(instr->value());
1184 LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) {
1185 LOperand* context = UseAny(instr->context()); // Deferred use.
1186 LOperand* input = UseRegisterAtStart(instr->value());
1189 Representation r = instr->value()->representation();
1196 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) {
1197 ASSERT(instr->representation().IsDouble());
1198 ASSERT(instr->value()->representation().IsDouble());
1199 LOperand* input = UseRegisterAtStart(instr->value());
1200 return MarkAsCall(DefineSameAsFirst(new(zone()) LMathLog(input)), instr);
1204 LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) {
1205 LOperand* input = UseRegisterAtStart(instr->value());
1211 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) {
1212 ASSERT(instr->representation().IsDouble());
1213 ASSERT(instr->value()->representation().IsDouble());
1214 LOperand* value = UseTempRegister(instr->value());
1222 LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) {
1223 LOperand* input = UseAtStart(instr->value());
1228 LInstruction* LChunkBuilder::DoMathPowHalf(HUnaryMathOperation* instr) {
1229 LOperand* input = UseRegisterAtStart(instr->value());
1236 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) {
1237 LOperand* context = UseFixed(instr->context(), esi);
1238 LOperand* constructor = UseFixed(instr->constructor(), edi);
1240 return MarkAsCall(DefineFixed(result, eax), instr);
1244 LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) {
1245 LOperand* context = UseFixed(instr->context(), esi);
1246 LOperand* constructor = UseFixed(instr->constructor(), edi);
1248 return MarkAsCall(DefineFixed(result, eax), instr);
1252 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
1253 LOperand* context = UseFixed(instr->context(), esi);
1254 LOperand* function = UseFixed(instr->function(), edi);
1256 return MarkAsCall(DefineFixed(call, eax), instr);
1260 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) {
1261 LOperand* context = UseFixed(instr->context(), esi);
1262 return MarkAsCall(DefineFixed(new(zone()) LCallRuntime(context), eax), instr);
1266 LInstruction* LChunkBuilder::DoRor(HRor* instr) {
1267 return DoShift(Token::ROR, instr);
1271 LInstruction* LChunkBuilder::DoShr(HShr* instr) {
1272 return DoShift(Token::SHR, instr);
1276 LInstruction* LChunkBuilder::DoSar(HSar* instr) {
1277 return DoShift(Token::SAR, instr);
1281 LInstruction* LChunkBuilder::DoShl(HShl* instr) {
1282 return DoShift(Token::SHL, instr);
1286 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) {
1287 if (instr->representation().IsSmiOrInteger32()) {
1288 ASSERT(instr->left()->representation().Equals(instr->representation()));
1289 ASSERT(instr->right()->representation().Equals(instr->representation()));
1290 ASSERT(instr->CheckFlag(HValue::kTruncatingToInt32));
1292 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
1293 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand());
1296 return DoArithmeticT(instr->op(), instr);
1301 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) {
1302 ASSERT(instr->representation().IsSmiOrInteger32());
1303 ASSERT(instr->left()->representation().Equals(instr->representation()));
1304 ASSERT(instr->right()->representation().Equals(instr->representation()));
1305 LOperand* dividend = UseRegister(instr->left());
1306 int32_t divisor = instr->right()->GetInteger32Constant();
1309 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1310 (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) ||
1311 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
1319 LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) {
1320 ASSERT(instr->representation().IsInteger32());
1321 ASSERT(instr->left()->representation().Equals(instr->representation()));
1322 ASSERT(instr->right()->representation().Equals(instr->representation()));
1323 LOperand* dividend = UseRegister(instr->left());
1324 int32_t divisor = instr->right()->GetInteger32Constant();
1330 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1331 !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
1338 LInstruction* LChunkBuilder::DoDivI(HDiv* instr) {
1339 ASSERT(instr->representation().IsSmiOrInteger32());
1340 ASSERT(instr->left()->representation().Equals(instr->representation()));
1341 ASSERT(instr->right()->representation().Equals(instr->representation()));
1342 LOperand* dividend = UseFixed(instr->left(), eax);
1343 LOperand* divisor = UseRegister(instr->right());
1347 if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1348 instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
1349 instr->CheckFlag(HValue::kCanOverflow) ||
1350 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
1357 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
1358 if (instr->representation().IsSmiOrInteger32()) {
1359 if (instr->RightIsPowerOf2()) {
1360 return DoDivByPowerOf2I(instr);
1361 } else if (instr->right()->IsConstant()) {
1362 return DoDivByConstI(instr);
1364 return DoDivI(instr);
1366 } else if (instr->representation().IsDouble()) {
1367 return DoArithmeticD(Token::DIV, instr);
1369 return DoArithmeticT(Token::DIV, instr);
1374 LInstruction* LChunkBuilder::DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr) {
1375 LOperand* dividend = UseRegisterAtStart(instr->left());
1376 int32_t divisor = instr->right()->GetInteger32Constant();
1379 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1380 (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) {
1387 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) {
1388 ASSERT(instr->representation().IsInteger32());
1389 ASSERT(instr->left()->representation().Equals(instr->representation()));
1390 ASSERT(instr->right()->representation().Equals(instr->representation()));
1391 LOperand* dividend = UseRegister(instr->left());
1392 int32_t divisor = instr->right()->GetInteger32Constant();
1396 ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) ||
1397 (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ?
1407 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) {
1414 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) {
1415 ASSERT(instr->representation().IsSmiOrInteger32());
1416 ASSERT(instr->left()->representation().Equals(instr->representation()));
1417 ASSERT(instr->right()->representation().Equals(instr->representation()));
1418 LOperand* dividend = UseFixed(instr->left(), eax);
1419 LOperand* divisor = UseRegister(instr->right());
1423 if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1424 instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
1425 instr->CheckFlag(HValue::kCanOverflow)) {
1432 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
1433 if (instr->RightIsPowerOf2()) {
1434 return DoFlooringDivByPowerOf2I(instr);
1435 } else if (instr->right()->IsConstant()) {
1436 return DoFlooringDivByConstI(instr);
1438 return DoFlooringDivI(instr);
1443 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) {
1444 ASSERT(instr->representation().IsSmiOrInteger32());
1445 ASSERT(instr->left()->representation().Equals(instr->representation()));
1446 ASSERT(instr->right()->representation().Equals(instr->representation()));
1447 LOperand* dividend = UseRegisterAtStart(instr->left());
1448 int32_t divisor = instr->right()->GetInteger32Constant();
1451 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1458 LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) {
1459 ASSERT(instr->representation().IsSmiOrInteger32());
1460 ASSERT(instr->left()->representation().Equals(instr->representation()));
1461 ASSERT(instr->right()->representation().Equals(instr->representation()));
1462 LOperand* dividend = UseRegister(instr->left());
1463 int32_t divisor = instr->right()->GetInteger32Constant();
1468 if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1475 LInstruction* LChunkBuilder::DoModI(HMod* instr) {
1476 ASSERT(instr->representation().IsSmiOrInteger32());
1477 ASSERT(instr->left()->representation().Equals(instr->representation()));
1478 ASSERT(instr->right()->representation().Equals(instr->representation()));
1479 LOperand* dividend = UseFixed(instr->left(), eax);
1480 LOperand* divisor = UseRegister(instr->right());
1484 if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1485 instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1492 LInstruction* LChunkBuilder::DoMod(HMod* instr) {
1493 if (instr->representation().IsSmiOrInteger32()) {
1494 if (instr->RightIsPowerOf2()) {
1495 return DoModByPowerOf2I(instr);
1496 } else if (instr->right()->IsConstant()) {
1497 return DoModByConstI(instr);
1499 return DoModI(instr);
1501 } else if (instr->representation().IsDouble()) {
1502 return DoArithmeticD(Token::MOD, instr);
1504 return DoArithmeticT(Token::MOD, instr);
1509 LInstruction* LChunkBuilder::DoMul(HMul* instr) {
1510 if (instr->representation().IsSmiOrInteger32()) {
1511 ASSERT(instr->left()->representation().Equals(instr->representation()));
1512 ASSERT(instr->right()->representation().Equals(instr->representation()));
1513 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
1514 LOperand* right = UseOrConstant(instr->BetterRightOperand());
1516 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1520 if (instr->CheckFlag(HValue::kCanOverflow) ||
1521 instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1525 } else if (instr->representation().IsDouble()) {
1526 return DoArithmeticD(Token::MUL, instr);
1528 return DoArithmeticT(Token::MUL, instr);
1533 LInstruction* LChunkBuilder::DoSub(HSub* instr) {
1534 if (instr->representation().IsSmiOrInteger32()) {
1535 ASSERT(instr->left()->representation().Equals(instr->representation()));
1536 ASSERT(instrinstr->representation()));
1537 LOperand* left = UseRegisterAtStart(instr->left());
1538 LOperand* right = UseOrConstantAtStart(instr->right());
1541 if (instr->CheckFlag(HValue::kCanOverflow)) {
1545 } else if (instr->representation().IsDouble()) {
1546 return DoArithmeticD(Token::SUB, instr);
1548 return DoArithmeticT(Token::SUB, instr);
1553 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
1554 if (instr->representation().IsSmiOrInteger32()) {
1555 ASSERT(instr->left()->representation().Equals(instr->representation()));
1556 ASSERT(instr->right()->representation().Equals(instr->representation()));
1561 bool use_lea = LAddI::UseLea(instr);
1562 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
1563 HValue* right_candidate = instr->BetterRightOperand();
1568 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow);
1576 } else if (instr->representation().IsDouble()) {
1577 return DoArithmeticD(Token::ADD, instr);
1578 } else if (instr->representation().IsExternal()) {
1579 ASSERT(instr->left()->representation().IsExternal());
1580 ASSERT(instr->right()->representation().IsInteger32());
1581 ASSERT(!instr->CheckFlag(HValue::kCanOverflow));
1582 bool use_lea = LAddI::UseLea(instr);
1583 LOperand* left = UseRegisterAtStart(instr->left());
1584 HValue* right_candidate = instr->right();
1594 return DoArithmeticT(Token::ADD, instr);
1599 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) {
1602 if (instr->representation().IsSmiOrInteger32()) {
1603 ASSERT(instr->left()->representation().Equals(instr->representation()));
1604 ASSERT(instr->right()->representation().Equals(instr->representation()));
1605 left = UseRegisterAtStart(instr->BetterLeftOperand());
1606 right = UseOrConstantAtStart(instr->BetterRightOperand());
1608 ASSERT(instr->representation().IsDouble());
1609 ASSERT(instr->left()->representation().IsDouble());
1610 ASSERT(instr->right()->representation().IsDouble());
1611 left = UseRegisterAtStart(instr->left());
1612 right = UseRegisterAtStart(instr->right());
1619 LInstruction* LChunkBuilder::DoPower(HPower* instr) {
1620 ASSERT(instr->representation().IsDouble());
1623 Representation exponent_type = instr->right()->representation();
1624 ASSERT(instr->left()->representation().IsDouble());
1625 LOperand* left = UseFixedDouble(instr->left(), xmm2);
1627 UseFixedDouble(instr->right(), xmm1) :
1628 UseFixed(instr->right(), eax);
1630 return MarkAsCall(DefineFixedDouble(result, xmm3), instr,
1635 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
1636 ASSERT(instr->left()->representation().IsSmiOrTagged());
1637 ASSERT(instr->right()->representation().IsSmiOrTagged());
1638 LOperand* context = UseFixed(instr->context(), esi);
1639 LOperand* left = UseFixed(instr->left(), edx);
1640 LOperand* right = UseFixed(instr->right(), eax);
1642 return MarkAsCall(DefineFixed(result, eax), instr);
1647 HCompareNumericAndBranch* instr) {
1648 Representation r = instr->representation();
1650 ASSERT(instr->left()->representation().Equals(r));
1651 ASSERT(instr->right()->representation().Equals(r));
1652 LOperand* left = UseRegisterOrConstantAtStart(instr->left());
1653 LOperand* right = UseOrConstantAtStart(instr->right());
1657 ASSERT(instr->left()->representation().IsDouble());
1658 ASSERT(instr->right()->representation().IsDouble());
1661 if (CanBeImmediateConstant(instr->left()) &&
1662 CanBeImmediateConstant(instr->right())) {
1665 left = UseConstant(instr->left());
1666 right = UseConstant(instr->right());
1668 left = UseRegisterAtStart(instr->left());
1669 right = UseRegisterAtStart(instr->right());
1677 HCompareObjectEqAndBranch* instr) {
1678 LOperand* left = UseRegisterAtStart(instr->left());
1679 LOperand* right = UseOrConstantAtStart(instr->right());
1685 HCompareHoleAndBranch* instr) {
1686 LOperand* value = UseRegisterAtStart(instr->value());
1692 HCompareMinusZeroAndBranch* instr) {
1693 LOperand* value = UseRegister(instr->value());
1699 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) {
1700 ASSERT(instr->value()->representation().IsSmiOrTagged());
1702 return new(zone()) LIsObjectAndBranch(UseRegister(instr->value()), temp);
1706 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) {
1707 ASSERT(instr->value()->representation().IsTagged());
1709 return new(zone()) LIsStringAndBranch(UseRegister(instr->value()), temp);
1713 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) {
1714 ASSERT(instr->value()->representation().IsTagged());
1715 return new(zone()) LIsSmiAndBranch(Use(instr->value()));
1720 HIsUndetectableAndBranch* instr) {
1721 ASSERT(instr->value()->representation().IsTagged());
1723 UseRegisterAtStart(instr->value()), TempRegister());
1728 HStringCompareAndBranch* instr) {
1729 ASSERT(instr->left()->representation().IsTagged());
1730 ASSERT(instr->right()->representation().IsTagged());
1731 LOperand* context = UseFixed(instr->context(), esi);
1732 LOperand* left = UseFixed(instr->left(), edx);
1733 LOperand* right = UseFixed(instr->right(), eax);
1738 return MarkAsCall(result, instr);
1743 HHasInstanceTypeAndBranch* instr) {
1744 ASSERT(instr->value()->representation().IsTagged());
1746 UseRegisterAtStart(instr->value()),
1752 HGetCachedArrayIndex* instr) {
1753 ASSERT(instr->value()->representation().IsTagged());
1754 LOperand* value = UseRegisterAtStart(instr->value());
1761 HHasCachedArrayIndexAndBranch* instr) {
1762 ASSERT(instr->value()->representation().IsTagged());
1764 UseRegisterAtStart(instr->value()));
1769 HClassOfTestAndBranch* instr) {
1770 ASSERT(instr->value()->representation().IsTagged());
1771 return new(zone()) LClassOfTestAndBranch(UseRegister(instr->value()),
1777 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) {
1778 LOperand* map = UseRegisterAtStart(instr->value());
1783 LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
1784 LOperand* date = UseFixed(instr->value(), eax);
1786 new(zone()) LDateField(date, FixedTemp(ecx), instr->index());
1787 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY);
1791 LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) {
1792 LOperand* string = UseRegisterAtStart(instr->string());
1793 LOperand* index = UseRegisterOrConstantAtStart(instr->index());
1798 LOperand* LChunkBuilder::GetSeqStringSetCharOperand(HSeqStringSetChar* instr) {
1799 if (instr->encoding() == String::ONE_BYTE_ENCODING) {
1801 return UseFixed(instr->value(), eax);
1803 return UseFixedOrConstant(instr->value(), eax);
1807 return UseRegisterAtStart(instr->value());
1809 return UseRegisterOrConstantAtStart(instr->value());
1815 LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) {
1816 LOperand* string = UseRegisterAtStart(instr->string());
1818 ? UseRegisterAtStart(instr->index())
1819 : UseRegisterOrConstantAtStart(instr->index());
1820 LOperand* value = GetSeqStringSetCharOperand(instr);
1821 LOperand* context = FLAG_debug_code ? UseFixed(instr->context(), esi) : NULL;
1825 result = MarkAsCall(result, instr);
1831 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
1832 if (!FLAG_debug_code && instr->skip_check()) return NULL;
1833 LOperand* index = UseRegisterOrConstantAtStart(instr->index());
1835 ? UseOrConstantAtStart(instr->length())
1836 : UseAtStart(instr->length());
1838 if (!FLAG_debug_code || !instr->skip_check()) {
1846 HBoundsCheckBaseIndexInformation* instr) {
1852 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
1859 LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) {
1872 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1873 Representation from = instr->from();
1874 Representation to = instr->to();
1875 HValue* val = instr->value();
1904 bool truncating = instr->CanTruncateToInt32();
1926 bool truncating = instr->CanTruncateToInt32();
1939 if (!instr->CheckFlag(HValue::kCanOverflow)) {
1953 if (instr->CheckFlag(HValue::kCanOverflow)) {
1971 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
1972 LOperand* value = UseAtStart(instr->value());
1974 if (!instr->value()->type().IsHeapObject()) {
1981 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) {
1982 LOperand* value = UseRegisterAtStart(instr->value());
1987 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
1988 instr->value());
1995 LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) {
2000 LOperand* value = instr->object_in_new_space()
2001 ? UseRegisterAtStart(instr->value()) : UseAtStart(instr->value());
2006 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
2007 if (instr->IsStabilityCheck()) return new(zone()) LCheckMaps;
2008 LOperand* value = UseRegisterAtStart(instr->value());
2010 if (instr->HasMigrationTarget()) {
2018 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
2019 HValue* value = instr->value();
2039 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) {
2040 HValue* value = instr->value();
2046 LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) {
2047 LOperand* lo = UseRegister(instr->lo());
2048 LOperand* hi = UseRegister(instr->hi());
2053 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
2054 LOperand* context = info()->IsStub() ? UseFixed(instr->context(), esi) : NULL;
2055 LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count());
2057 UseFixed(instr->value(), eax), context, parameter_count);
2061 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
2062 Representation r = instr->representation();
2068 double value = instr->DoubleValue();
2083 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
2085 return instr->RequiresHoleCheck()
2091 LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
2092 LOperand* context = UseFixed(instr->context(), esi);
2093 LOperand* global_object = UseFixed(instr->global_object(), edx);
2096 return MarkAsCall(DefineFixed(result, eax), instr);
2100 LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
2102 new(zone()) LStoreGlobalCell(UseRegister(instr->value()));
2103 return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
2107 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
2108 LOperand* context = UseRegisterAtStart(instr->value());
2111 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
2118 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
2121 LOperand* context = UseRegister(instr->context());
2122 if (instr->NeedsWriteBarrier()) {
2123 value = UseTempRegister(instr->value());
2126 value = UseRegister(instr->value());
2130 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
2137 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
2138 LOperand* obj = (instr->access().IsExternalMemory() &&
2139 instr->access().offset() == 0)
2140 ? UseRegisterOrConstantAtStart(instr->object())
2141 : UseRegisterAtStart(instr->object());
2146 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
2147 LOperand* context = UseFixed(instr->context(), esi);
2148 LOperand* object = UseFixed(instr->object(), edx);
2150 return MarkAsCall(DefineFixed(result, eax), instr);
2155 HLoadFunctionPrototype* instr) {
2157 new(zone()) LLoadFunctionPrototype(UseRegister(instr->function()),
2162 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) {
2167 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
2168 ASSERT(instr->key()->representation().IsSmiOrInteger32());
2169 ElementsKind elements_kind = instr->elements_kind();
2171 instr->key()->representation(), elements_kind);
2173 ? UseTempRegister(instr->key())
2174 : UseRegisterOrConstantAtStart(instr->key());
2177 if (!instr->is_typed_elements()) {
2178 LOperand* obj = UseRegisterAtStart(instr->elements());
2182 (instr->representation().IsInteger32() &&
2183 !(IsDoubleOrFloatElementsKind(instr->elements_kind()))) ||
2184 (instr->representation().IsDouble() &&
2185 (IsDoubleOrFloatElementsKind(instr->elements_kind()))));
2186 LOperand* backing_store = UseRegister(instr->elements());
2190 if ((instr->is_external() || instr->is_fixed_typed_array()) ?
2192 ((instr->elements_kind() == EXTERNAL_UINT32_ELEMENTS ||
2193 instr->elements_kind() == UINT32_ELEMENTS) &&
2194 !instr->CheckFlag(HInstruction::kUint32)) :
2197 instr->RequiresHoleCheck()) {
2204 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
2205 LOperand* context = UseFixed(instr->context(), esi);
2206 LOperand* object = UseFixed(instr->object(), edx);
2207 LOperand* key = UseFixed(instr->key(), ecx);
2211 return MarkAsCall(DefineFixed(result, eax), instr);
2215 LOperand* LChunkBuilder::GetStoreKeyedValueOperand(HStoreKeyed* instr) {
2216 ElementsKind elements_kind = instr->elements_kind();
2227 return UseFixed(instr->value(), eax);
2230 return UseRegister(instr->value());
2234 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
2235 if (!instr->is_typed_elements()) {
2236 ASSERT(instr->elements()->representation().IsTagged());
2237 ASSERT(instr->key()->representation().IsInteger32() ||
2238 instr->key()->representation().IsSmi());
2240 if (instr->value()->representation().IsDouble()) {
2241 LOperand* object = UseRegisterAtStart(instr->elements());
2243 val = UseRegisterAtStart(instr->value());
2244 LOperand* key = UseRegisterOrConstantAtStart(instr->key());
2247 ASSERT(instr->value()->representation().IsSmiOrTagged());
2248 bool needs_write_barrier = instr->NeedsWriteBarrier();
2250 LOperand* obj = UseRegister(instr->elements());
2254 val = UseTempRegister(instr->value());
2255 key = UseTempRegister(instr->key());
2257 val = UseRegisterOrConstantAtStart(instr->value());
2258 key = UseRegisterOrConstantAtStart(instr->key());
2264 ElementsKind elements_kind = instr->elements_kind();
2266 (instr->value()->representation().IsInteger32() &&
2268 (instr->value()->representation().IsDouble() &&
2270 ASSERT((instr->is_fixed_typed_array() &&
2271 instr->elements()->representation().IsTagged()) ||
2272 (instr->is_external() &&
2273 instr->elements()->representation().IsExternal()));
2275 LOperand* backing_store = UseRegister(instr->elements());
2276 LOperand* val = GetStoreKeyedValueOperand(instr);
2278 instr->key()->representation(), elements_kind);
2280 ? UseTempRegister(instr->key())
2281 : UseRegisterOrConstantAtStart(instr->key());
2286 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
2287 LOperand* context = UseFixed(instr->context(), esi);
2288 LOperand* object = UseFixed(instr->object(), edx);
2289 LOperand* key = UseFixed(instr->key(), ecx);
2290 LOperand* value = UseFixed(instr->value(), eax);
2292 ASSERT(instr->object()->representation().IsTagged());
2293 ASSERT(instr->key()->representation().IsTagged());
2294 ASSERT(instr->value()->representation().IsTagged());
2298 return MarkAsCall(result, instr);
2303 HTransitionElementsKind* instr) {
2304 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
2305 LOperand* object = UseRegister(instr->object());
2313 LOperand* object = UseFixed(instr->object(), eax);
2314 LOperand* context = UseFixed(instr->context(), esi);
2317 return MarkAsCall(result, instr);
2323 HTrapAllocationMemento* instr) {
2324 LOperand* object = UseRegister(instr->object());
2332 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
2333 bool is_in_object = instr->access().IsInobject();
2334 bool is_external_location = instr->access().IsExternalMemory() &&
2335 instr->access().offset() == 0;
2336 bool needs_write_barrier = instr->NeedsWriteBarrier();
2337 bool needs_write_barrier_for_map = instr->has_transition() &&
2338 instr->NeedsWriteBarrierForMap();
2343 ? UseRegister(instr->object())
2344 : UseTempRegister(instr->object());
2349 obj = UseRegisterOrConstant(instr->object());
2352 ? UseRegister(instr->object())
2353 : UseRegisterAtStart(instr->object());
2356 bool can_be_constant = instr->value()->IsConstant() &&
2357 HConstant::cast(instr->value())->NotInNewSpace() &&
2358 !instr->field_representation().IsDouble();
2361 if (instr->field_representation().IsInteger8() ||
2362 instr->field_representation().IsUInteger8()) {
2365 val = UseFixed(instr->value(), eax);
2367 val = UseTempRegister(instr->value());
2369 val = UseRegisterOrConstant(instr->value());
2370 } else if (instr->field_representation().IsSmi()) {
2371 val = UseTempRegister(instr->value());
2372 } else if (instr->field_representation().IsDouble()) {
2373 val = UseRegisterAtStart(instr->value());
2375 val = UseRegister(instr->value());
2390 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
2391 LOperand* context = UseFixed(instr->context(), esi);
2392 LOperand* object = UseFixed(instr->object(), edx);
2393 LOperand* value = UseFixed(instr->value(), eax);
2397 return MarkAsCall(result, instr);
2401 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) {
2402 LOperand* context = UseFixed(instr->context(), esi);
2403 LOperand* left = UseFixed(instr->left(), edx);
2404 LOperand* right = UseFixed(instr->right(), eax);
2406 return MarkAsCall(DefineFixed(string_add, eax), instr);
2410 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
2411 LOperand* string = UseTempRegister(instr->string());
2412 LOperand* index = UseTempRegister(instr->index());
2413 LOperand* context = UseAny(instr->context());
2420 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
2421 LOperand* char_code = UseRegister(instr->value());
2422 LOperand* context = UseAny(instr->context());
2429 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) {
2431 LOperand* context = UseAny(instr->context());
2432 LOperand* size = instr->size()->IsConstant()
2433 ? UseConstant(instr->size())
2434 : UseTempRegister(instr->size());
2441 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) {
2442 LOperand* context = UseFixed(instr->context(), esi);
2444 DefineFixed(new(zone()) LRegExpLiteral(context), eax), instr);
2448 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) {
2449 LOperand* context = UseFixed(instr->context(), esi);
2451 DefineFixed(new(zone()) LFunctionLiteral(context), eax), instr);
2455 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
2458 current_block_->last_environment()->set_ast_id(instr->ast_id());
2463 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
2465 if (instr->kind() == HParameter::STACK_PARAMETER) {
2466 int spill_index = chunk()->GetParameterStackSlot(instr->index());
2472 int index = static_cast<int>(instr->index());
2479 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
2482 int env_index = instr->index();
2484 if (instr->environment()->is_parameter_index(env_index)) {
2487 spill_index = env_index - instr->environment()->first_local_index();
2502 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) {
2503 LOperand* context = UseFixed(instr->context(), esi);
2505 return MarkAsCall(DefineFixed(result, eax), instr);
2509 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
2518 LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) {
2519 instr->ReplayEnvironment(current_block_->last_environment());
2526 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
2528 LOperand* args = UseRegister(instr->arguments());
2531 if (instr->length()->IsConstant() && instr->index()->IsConstant()) {
2532 length = UseRegisterOrConstant(instr->length());
2533 index = UseOrConstant(instr->index());
2535 length = UseTempRegister(instr->length());
2536 index = Use(instr->index());
2542 LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) {
2543 LOperand* object = UseFixed(instr->value(), eax);
2545 return MarkAsCall(DefineFixed(result, eax), instr);
2549 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
2550 LOperand* context = UseFixed(instr->context(), esi);
2551 LOperand* value = UseAtStart(instr->value());
2553 return MarkAsCall(DefineFixed(result, eax), instr);
2557 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
2558 return new(zone()) LTypeofIsAndBranch(UseTempRegister(instr->value()));
2563 HIsConstructCallAndBranch* instr) {
2568 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
2569 instr->ReplayEnvironment(current_block_->last_environment());
2574 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
2576 if (instr->is_function_entry()) {
2577 LOperand* context = UseFixed(instr->context(), esi);
2578 return MarkAsCall(new(zone()) LStackCheck(context), instr);
2580 ASSERT(instr->is_backwards_branch());
2581 LOperand* context = UseAny(instr->context());
2588 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
2590 outer->set_ast_id(instr->ReturnId());
2592 HEnvironment* inner = outer->CopyForInlining(instr->closure(),
2593 instr->arguments_count(),
2594 instr->function(),
2596 instr->inlining_kind());
2598 if (instr->arguments_var() != NULL && instr->arguments_object()->IsLinked()) {
2599 inner->Bind(instr->arguments_var(), instr->arguments_object());
2601 inner->set_entry(instr);
2603 chunk_->AddInlinedClosure(instr->closure());
2608 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
2616 ASSERT(instr->argument_delta() == -argument_count);
2626 LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) {
2627 LOperand* context = UseFixed(instr->context(), esi);
2628 LOperand* object = UseFixed(instr->enumerable(), eax);
2630 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY);
2634 LInstruction* LChunkBuilder::DoForInCacheArray(HForInCacheArray* instr) {
2635 LOperand* map = UseRegister(instr->map());
2641 LInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) {
2642 LOperand* value = UseRegisterAtStart(instr->value());
2643 LOperand* map = UseRegisterAtStart(instr->map());
2648 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
2649 LOperand* object = UseRegister(instr->object());
2650 LOperand* index = UseTempRegister(instr->index());
2657 LInstruction* LChunkBuilder::DoStoreFrameContext(HStoreFrameContext* instr) {
2658 LOperand* context = UseRegisterAtStart(instr->context());
2664 HAllocateBlockContext* instr) {
2665 LOperand* context = UseFixed(instr->context(), esi);
2666 LOperand* function = UseRegisterAtStart(instr->function());
2669 return MarkAsCall(DefineFixed(result, esi), instr);