Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: src/x64/lithium-x64.cc

Issue 196133017: Experimental parser: merge r19949 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/lithium-x64.h ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 HInstruction* hinstr, 623 HInstruction* hinstr,
624 CanDeoptimize can_deoptimize) { 624 CanDeoptimize can_deoptimize) {
625 info()->MarkAsNonDeferredCalling(); 625 info()->MarkAsNonDeferredCalling();
626 626
627 #ifdef DEBUG 627 #ifdef DEBUG
628 instr->VerifyCall(); 628 instr->VerifyCall();
629 #endif 629 #endif
630 instr->MarkAsCall(); 630 instr->MarkAsCall();
631 instr = AssignPointerMap(instr); 631 instr = AssignPointerMap(instr);
632 632
633 if (hinstr->HasObservableSideEffects()) {
634 ASSERT(hinstr->next()->IsSimulate());
635 HSimulate* sim = HSimulate::cast(hinstr->next());
636 ASSERT(instruction_pending_deoptimization_environment_ == NULL);
637 ASSERT(pending_deoptimization_ast_id_.IsNone());
638 instruction_pending_deoptimization_environment_ = instr;
639 pending_deoptimization_ast_id_ = sim->ast_id();
640 }
641
642 // If instruction does not have side-effects lazy deoptimization 633 // If instruction does not have side-effects lazy deoptimization
643 // after the call will try to deoptimize to the point before the call. 634 // after the call will try to deoptimize to the point before the call.
644 // Thus we still need to attach environment to this call even if 635 // Thus we still need to attach environment to this call even if
645 // call sequence can not deoptimize eagerly. 636 // call sequence can not deoptimize eagerly.
646 bool needs_environment = 637 bool needs_environment =
647 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || 638 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) ||
648 !hinstr->HasObservableSideEffects(); 639 !hinstr->HasObservableSideEffects();
649 if (needs_environment && !instr->HasEnvironment()) { 640 if (needs_environment && !instr->HasEnvironment()) {
650 instr = AssignEnvironment(instr); 641 instr = AssignEnvironment(instr);
651 } 642 }
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 } 900 }
910 #endif 901 #endif
911 902
912 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { 903 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
913 instr = AssignPointerMap(instr); 904 instr = AssignPointerMap(instr);
914 } 905 }
915 if (FLAG_stress_environments && !instr->HasEnvironment()) { 906 if (FLAG_stress_environments && !instr->HasEnvironment()) {
916 instr = AssignEnvironment(instr); 907 instr = AssignEnvironment(instr);
917 } 908 }
918 chunk_->AddInstruction(instr, current_block_); 909 chunk_->AddInstruction(instr, current_block_);
910
911 if (instr->IsCall()) {
912 HValue* hydrogen_value_for_lazy_bailout = current;
913 LInstruction* instruction_needing_environment = NULL;
914 if (current->HasObservableSideEffects()) {
915 HSimulate* sim = HSimulate::cast(current->next());
916 instruction_needing_environment = instr;
917 sim->ReplayEnvironment(current_block_->last_environment());
918 hydrogen_value_for_lazy_bailout = sim;
919 }
920 LInstruction* bailout = AssignEnvironment(new(zone()) LLazyBailout());
921 bailout->set_hydrogen_value(hydrogen_value_for_lazy_bailout);
922 chunk_->AddInstruction(bailout, current_block_);
923 if (instruction_needing_environment != NULL) {
924 // Store the lazy deopt environment with the instruction if needed.
925 // Right now it is only used for LInstanceOfKnownGlobal.
926 instruction_needing_environment->
927 SetDeferredLazyDeoptimizationEnvironment(bailout->environment());
928 }
929 }
919 } 930 }
920 current_instruction_ = old_current; 931 current_instruction_ = old_current;
921 } 932 }
922 933
923 934
924 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { 935 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
925 return new(zone()) LGoto(instr->FirstSuccessor()); 936 return new(zone()) LGoto(instr->FirstSuccessor());
926 } 937 }
927 938
928 939
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1115 1126
1116 1127
1117 LInstruction* LChunkBuilder::DoMathFloor(HUnaryMathOperation* instr) { 1128 LInstruction* LChunkBuilder::DoMathFloor(HUnaryMathOperation* instr) {
1118 LOperand* input = UseRegisterAtStart(instr->value()); 1129 LOperand* input = UseRegisterAtStart(instr->value());
1119 LMathFloor* result = new(zone()) LMathFloor(input); 1130 LMathFloor* result = new(zone()) LMathFloor(input);
1120 return AssignEnvironment(DefineAsRegister(result)); 1131 return AssignEnvironment(DefineAsRegister(result));
1121 } 1132 }
1122 1133
1123 1134
1124 LInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) { 1135 LInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) {
1125 LOperand* input = UseRegisterAtStart(instr->value()); 1136 LOperand* input = UseRegister(instr->value());
1126 LMathRound* result = new(zone()) LMathRound(input); 1137 LOperand* temp = FixedTemp(xmm4);
1138 LMathRound* result = new(zone()) LMathRound(input, temp);
1127 return AssignEnvironment(DefineAsRegister(result)); 1139 return AssignEnvironment(DefineAsRegister(result));
1128 } 1140 }
1129 1141
1130 1142
1131 LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) { 1143 LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) {
1132 LOperand* context = UseAny(instr->context()); 1144 LOperand* context = UseAny(instr->context());
1133 LOperand* input = UseRegisterAtStart(instr->value()); 1145 LOperand* input = UseRegisterAtStart(instr->value());
1134 LMathAbs* result = new(zone()) LMathAbs(context, input); 1146 LMathAbs* result = new(zone()) LMathAbs(context, input);
1135 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); 1147 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
1136 } 1148 }
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1235 1247
1236 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); 1248 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
1237 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); 1249 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand());
1238 return DefineSameAsFirst(new(zone()) LBitI(left, right)); 1250 return DefineSameAsFirst(new(zone()) LBitI(left, right));
1239 } else { 1251 } else {
1240 return DoArithmeticT(instr->op(), instr); 1252 return DoArithmeticT(instr->op(), instr);
1241 } 1253 }
1242 } 1254 }
1243 1255
1244 1256
1257 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) {
1258 ASSERT(instr->representation().IsSmiOrInteger32());
1259 ASSERT(instr->left()->representation().Equals(instr->representation()));
1260 ASSERT(instr->right()->representation().Equals(instr->representation()));
1261 LOperand* dividend = UseRegister(instr->left());
1262 int32_t divisor = instr->right()->GetInteger32Constant();
1263 LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I(
1264 dividend, divisor));
1265 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1266 (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) ||
1267 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
1268 divisor != 1 && divisor != -1)) {
1269 result = AssignEnvironment(result);
1270 }
1271 return result;
1272 }
1273
1274
1275 LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) {
1276 ASSERT(instr->representation().IsInteger32());
1277 ASSERT(instr->left()->representation().Equals(instr->representation()));
1278 ASSERT(instr->right()->representation().Equals(instr->representation()));
1279 LOperand* dividend = UseRegister(instr->left());
1280 int32_t divisor = instr->right()->GetInteger32Constant();
1281 LOperand* temp1 = FixedTemp(rax);
1282 LOperand* temp2 = FixedTemp(rdx);
1283 LInstruction* result = DefineFixed(new(zone()) LDivByConstI(
1284 dividend, divisor, temp1, temp2), rdx);
1285 if (divisor == 0 ||
1286 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1287 !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
1288 result = AssignEnvironment(result);
1289 }
1290 return result;
1291 }
1292
1293
1294 LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) {
1295 ASSERT(instr->representation().IsSmiOrInteger32());
1296 ASSERT(instr->left()->representation().Equals(instr->representation()));
1297 ASSERT(instr->right()->representation().Equals(instr->representation()));
1298 LOperand* dividend = UseFixed(instr->left(), rax);
1299 LOperand* divisor = UseRegister(instr->right());
1300 LOperand* temp = FixedTemp(rdx);
1301 LInstruction* result = DefineFixed(new(zone()) LDivI(
1302 dividend, divisor, temp), rax);
1303 if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1304 instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
1305 instr->CheckFlag(HValue::kCanOverflow) ||
1306 (!instr->IsMathFloorOfDiv() &&
1307 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
1308 result = AssignEnvironment(result);
1309 }
1310 return result;
1311 }
1312
1313
1245 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { 1314 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
1246 if (instr->representation().IsSmiOrInteger32()) { 1315 if (instr->representation().IsSmiOrInteger32()) {
1247 ASSERT(instr->left()->representation().Equals(instr->representation()));
1248 ASSERT(instr->right()->representation().Equals(instr->representation()));
1249 if (instr->RightIsPowerOf2()) { 1316 if (instr->RightIsPowerOf2()) {
1250 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); 1317 return DoDivByPowerOf2I(instr);
1251 LOperand* value = UseRegister(instr->left()); 1318 } else if (instr->right()->IsConstant()) {
1252 LDivI* div = 1319 return DoDivByConstI(instr);
1253 new(zone()) LDivI(value, UseOrConstant(instr->right()), NULL); 1320 } else {
1254 return AssignEnvironment(DefineAsRegister(div)); 1321 return DoDivI(instr);
1255 } 1322 }
1256 // The temporary operand is necessary to ensure that right is not allocated
1257 // into rdx.
1258 LOperand* temp = FixedTemp(rdx);
1259 LOperand* dividend = UseFixed(instr->left(), rax);
1260 LOperand* divisor = UseRegister(instr->right());
1261 LDivI* result = new(zone()) LDivI(dividend, divisor, temp);
1262 return AssignEnvironment(DefineFixed(result, rax));
1263 } else if (instr->representation().IsDouble()) { 1323 } else if (instr->representation().IsDouble()) {
1264 return DoArithmeticD(Token::DIV, instr); 1324 return DoArithmeticD(Token::DIV, instr);
1265 } else { 1325 } else {
1266 return DoArithmeticT(Token::DIV, instr); 1326 return DoArithmeticT(Token::DIV, instr);
1267 } 1327 }
1268 } 1328 }
1269 1329
1270 1330
1331 LInstruction* LChunkBuilder::DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr) {
1332 LOperand* dividend = UseRegisterAtStart(instr->left());
1333 int32_t divisor = instr->right()->GetInteger32Constant();
1334 LInstruction* result = DefineSameAsFirst(new(zone()) LFlooringDivByPowerOf2I(
1335 dividend, divisor));
1336 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1337 (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) {
1338 result = AssignEnvironment(result);
1339 }
1340 return result;
1341 }
1342
1343
1344 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) {
1345 ASSERT(instr->representation().IsInteger32());
1346 ASSERT(instr->left()->representation().Equals(instr->representation()));
1347 ASSERT(instr->right()->representation().Equals(instr->representation()));
1348 LOperand* dividend = UseRegister(instr->left());
1349 int32_t divisor = instr->right()->GetInteger32Constant();
1350 LOperand* temp1 = FixedTemp(rax);
1351 LOperand* temp2 = FixedTemp(rdx);
1352 LInstruction* result =
1353 DefineFixed(new(zone()) LFlooringDivByConstI(dividend,
1354 divisor,
1355 temp1,
1356 temp2),
1357 rdx);
1358 bool can_deopt =
1359 divisor == 0 ||
1360 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0);
1361 return can_deopt ? AssignEnvironment(result) : result;
1362 }
1363
1364
1271 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { 1365 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
1272 HValue* right = instr->right(); 1366 if (instr->RightIsPowerOf2()) {
1273 if (!right->IsConstant()) { 1367 return DoFlooringDivByPowerOf2I(instr);
1274 ASSERT(right->representation().IsInteger32()); 1368 } else if (false && instr->right()->IsConstant()) {
1275 // The temporary operand is necessary to ensure that right is not allocated 1369 return DoFlooringDivByConstI(instr); // TODO(svenpanne) Fix and re-enable.
1276 // into rdx.
1277 LOperand* temp = FixedTemp(rdx);
1278 LOperand* dividend = UseFixed(instr->left(), rax);
1279 LOperand* divisor = UseRegister(instr->right());
1280 LDivI* flooring_div = new(zone()) LDivI(dividend, divisor, temp);
1281 return AssignEnvironment(DefineFixed(flooring_div, rax));
1282 }
1283
1284 ASSERT(right->IsConstant() && HConstant::cast(right)->HasInteger32Value());
1285 LOperand* divisor = chunk_->DefineConstantOperand(HConstant::cast(right));
1286 int32_t divisor_si = HConstant::cast(right)->Integer32Value();
1287 if (divisor_si == 0) {
1288 LOperand* dividend = UseRegister(instr->left());
1289 return AssignEnvironment(DefineAsRegister(
1290 new(zone()) LMathFloorOfDiv(dividend, divisor, NULL)));
1291 } else if (IsPowerOf2(abs(divisor_si))) {
1292 LOperand* dividend = UseRegisterAtStart(instr->left());
1293 LInstruction* result = DefineAsRegister(
1294 new(zone()) LMathFloorOfDiv(dividend, divisor, NULL));
1295 return divisor_si < 0 ? AssignEnvironment(result) : result;
1296 } else { 1370 } else {
1297 // use two r64 1371 return DoDivI(instr);
1298 LOperand* dividend = UseRegisterAtStart(instr->left());
1299 LOperand* temp = TempRegister();
1300 LInstruction* result = DefineAsRegister(
1301 new(zone()) LMathFloorOfDiv(dividend, divisor, temp));
1302 return divisor_si < 0 ? AssignEnvironment(result) : result;
1303 } 1372 }
1304 } 1373 }
1305 1374
1306 1375
1376 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) {
1377 ASSERT(instr->representation().IsSmiOrInteger32());
1378 ASSERT(instr->left()->representation().Equals(instr->representation()));
1379 ASSERT(instr->right()->representation().Equals(instr->representation()));
1380 LOperand* dividend = UseRegisterAtStart(instr->left());
1381 int32_t divisor = instr->right()->GetInteger32Constant();
1382 LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I(
1383 dividend, divisor));
1384 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1385 result = AssignEnvironment(result);
1386 }
1387 return result;
1388 }
1389
1390
1391 LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) {
1392 ASSERT(instr->representation().IsSmiOrInteger32());
1393 ASSERT(instr->left()->representation().Equals(instr->representation()));
1394 ASSERT(instr->right()->representation().Equals(instr->representation()));
1395 LOperand* dividend = UseRegister(instr->left());
1396 int32_t divisor = instr->right()->GetInteger32Constant();
1397 LOperand* temp1 = FixedTemp(rax);
1398 LOperand* temp2 = FixedTemp(rdx);
1399 LInstruction* result = DefineFixed(new(zone()) LModByConstI(
1400 dividend, divisor, temp1, temp2), rax);
1401 if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1402 result = AssignEnvironment(result);
1403 }
1404 return result;
1405 }
1406
1407
1408 LInstruction* LChunkBuilder::DoModI(HMod* instr) {
1409 ASSERT(instr->representation().IsSmiOrInteger32());
1410 ASSERT(instr->left()->representation().Equals(instr->representation()));
1411 ASSERT(instr->right()->representation().Equals(instr->representation()));
1412 LOperand* dividend = UseFixed(instr->left(), rax);
1413 LOperand* divisor = UseRegister(instr->right());
1414 LOperand* temp = FixedTemp(rdx);
1415 LInstruction* result = DefineFixed(new(zone()) LModI(
1416 dividend, divisor, temp), rdx);
1417 if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1418 instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1419 result = AssignEnvironment(result);
1420 }
1421 return result;
1422 }
1423
1424
1307 LInstruction* LChunkBuilder::DoMod(HMod* instr) { 1425 LInstruction* LChunkBuilder::DoMod(HMod* instr) {
1308 HValue* left = instr->left();
1309 HValue* right = instr->right();
1310 if (instr->representation().IsSmiOrInteger32()) { 1426 if (instr->representation().IsSmiOrInteger32()) {
1311 ASSERT(left->representation().Equals(instr->representation()));
1312 ASSERT(right->representation().Equals(instr->representation()));
1313 if (instr->RightIsPowerOf2()) { 1427 if (instr->RightIsPowerOf2()) {
1314 ASSERT(!right->CanBeZero()); 1428 return DoModByPowerOf2I(instr);
1315 LModI* mod = new(zone()) LModI(UseRegisterAtStart(left), 1429 } else if (instr->right()->IsConstant()) {
1316 UseOrConstant(right), 1430 return DoModByConstI(instr);
1317 NULL);
1318 LInstruction* result = DefineSameAsFirst(mod);
1319 return (left->CanBeNegative() &&
1320 instr->CheckFlag(HValue::kBailoutOnMinusZero))
1321 ? AssignEnvironment(result)
1322 : result;
1323 } else { 1431 } else {
1324 // The temporary operand is necessary to ensure that right is not 1432 return DoModI(instr);
1325 // allocated into edx.
1326 LModI* mod = new(zone()) LModI(UseFixed(left, rax),
1327 UseRegister(right),
1328 FixedTemp(rdx));
1329 LInstruction* result = DefineFixed(mod, rdx);
1330 return (right->CanBeZero() ||
1331 (left->RangeCanInclude(kMinInt) &&
1332 right->RangeCanInclude(-1) &&
1333 instr->CheckFlag(HValue::kBailoutOnMinusZero)) ||
1334 (left->CanBeNegative() &&
1335 instr->CanBeZero() &&
1336 instr->CheckFlag(HValue::kBailoutOnMinusZero)))
1337 ? AssignEnvironment(result)
1338 : result;
1339 } 1433 }
1340 } else if (instr->representation().IsDouble()) { 1434 } else if (instr->representation().IsDouble()) {
1341 return DoArithmeticD(Token::MOD, instr); 1435 return DoArithmeticD(Token::MOD, instr);
1342 } else { 1436 } else {
1343 return DoArithmeticT(Token::MOD, instr); 1437 return DoArithmeticT(Token::MOD, instr);
1344 } 1438 }
1345 } 1439 }
1346 1440
1347 1441
1348 LInstruction* LChunkBuilder::DoMul(HMul* instr) { 1442 LInstruction* LChunkBuilder::DoMul(HMul* instr) {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1428 } else { 1522 } else {
1429 return DoArithmeticT(Token::ADD, instr); 1523 return DoArithmeticT(Token::ADD, instr);
1430 } 1524 }
1431 return NULL; 1525 return NULL;
1432 } 1526 }
1433 1527
1434 1528
1435 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { 1529 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) {
1436 LOperand* left = NULL; 1530 LOperand* left = NULL;
1437 LOperand* right = NULL; 1531 LOperand* right = NULL;
1438 if (instr->representation().IsSmiOrInteger32()) { 1532 ASSERT(instr->left()->representation().Equals(instr->representation()));
1439 ASSERT(instr->left()->representation().Equals(instr->representation())); 1533 ASSERT(instr->right()->representation().Equals(instr->representation()));
1440 ASSERT(instr->right()->representation().Equals(instr->representation())); 1534 if (instr->representation().IsSmi()) {
1535 left = UseRegisterAtStart(instr->BetterLeftOperand());
1536 right = UseAtStart(instr->BetterRightOperand());
1537 } else if (instr->representation().IsInteger32()) {
1441 left = UseRegisterAtStart(instr->BetterLeftOperand()); 1538 left = UseRegisterAtStart(instr->BetterLeftOperand());
1442 right = UseOrConstantAtStart(instr->BetterRightOperand()); 1539 right = UseOrConstantAtStart(instr->BetterRightOperand());
1443 } else { 1540 } else {
1444 ASSERT(instr->representation().IsDouble()); 1541 ASSERT(instr->representation().IsDouble());
1445 ASSERT(instr->left()->representation().IsDouble());
1446 ASSERT(instr->right()->representation().IsDouble());
1447 left = UseRegisterAtStart(instr->left()); 1542 left = UseRegisterAtStart(instr->left());
1448 right = UseRegisterAtStart(instr->right()); 1543 right = UseRegisterAtStart(instr->right());
1449 } 1544 }
1450 LMathMinMax* minmax = new(zone()) LMathMinMax(left, right); 1545 LMathMinMax* minmax = new(zone()) LMathMinMax(left, right);
1451 return DefineSameAsFirst(minmax); 1546 return DefineSameAsFirst(minmax);
1452 } 1547 }
1453 1548
1454 1549
1455 LInstruction* LChunkBuilder::DoPower(HPower* instr) { 1550 LInstruction* LChunkBuilder::DoPower(HPower* instr) {
1456 ASSERT(instr->representation().IsDouble()); 1551 ASSERT(instr->representation().IsDouble());
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
1737 ASSERT(to.IsInteger32()); 1832 ASSERT(to.IsInteger32());
1738 LOperand* value = UseRegister(instr->value()); 1833 LOperand* value = UseRegister(instr->value());
1739 return AssignEnvironment( 1834 return AssignEnvironment(
1740 DefineAsRegister(new(zone()) LDoubleToI(value))); 1835 DefineAsRegister(new(zone()) LDoubleToI(value)));
1741 } 1836 }
1742 } else if (from.IsInteger32()) { 1837 } else if (from.IsInteger32()) {
1743 info()->MarkAsDeferredCalling(); 1838 info()->MarkAsDeferredCalling();
1744 if (to.IsTagged()) { 1839 if (to.IsTagged()) {
1745 HValue* val = instr->value(); 1840 HValue* val = instr->value();
1746 LOperand* value = UseRegister(val); 1841 LOperand* value = UseRegister(val);
1747 if (val->CheckFlag(HInstruction::kUint32)) { 1842 if (!instr->CheckFlag(HValue::kCanOverflow)) {
1748 LOperand* temp = FixedTemp(xmm1); 1843 return DefineAsRegister(new(zone()) LSmiTag(value));
1749 LNumberTagU* result = new(zone()) LNumberTagU(value, temp); 1844 } else if (val->CheckFlag(HInstruction::kUint32)) {
1845 LOperand* temp1 = TempRegister();
1846 LOperand* temp2 = FixedTemp(xmm1);
1847 LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2);
1750 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); 1848 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
1751 } else if (val->HasRange() && val->range()->IsInSmiRange()) {
1752 return DefineSameAsFirst(new(zone()) LSmiTag(value));
1753 } else { 1849 } else {
1754 LNumberTagI* result = new(zone()) LNumberTagI(value); 1850 LNumberTagI* result = new(zone()) LNumberTagI(value);
1755 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); 1851 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
1756 } 1852 }
1757 } else if (to.IsSmi()) { 1853 } else if (to.IsSmi()) {
1758 HValue* val = instr->value(); 1854 HValue* val = instr->value();
1759 LOperand* value = UseRegister(val); 1855 LOperand* value = UseRegister(val);
1760 LInstruction* result = NULL; 1856 LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value));
1761 if (val->CheckFlag(HInstruction::kUint32)) { 1857 if (instr->CheckFlag(HValue::kCanOverflow)) {
1762 result = DefineAsRegister(new(zone()) LUint32ToSmi(value)); 1858 ASSERT(val->CheckFlag(HValue::kUint32));
1763 if (val->HasRange() && val->range()->IsInSmiRange() && 1859 result = AssignEnvironment(result);
1764 val->range()->upper() != kMaxInt) {
1765 return result;
1766 }
1767 } else {
1768 result = DefineAsRegister(new(zone()) LInteger32ToSmi(value));
1769 if (val->HasRange() && val->range()->IsInSmiRange()) {
1770 return result;
1771 }
1772 } 1860 }
1773 return AssignEnvironment(result); 1861 return result;
1774 } else { 1862 } else {
1775 if (instr->value()->CheckFlag(HInstruction::kUint32)) { 1863 if (instr->value()->CheckFlag(HInstruction::kUint32)) {
1776 LOperand* temp = FixedTemp(xmm1); 1864 LOperand* temp = FixedTemp(xmm1);
1777 return DefineAsRegister( 1865 return DefineAsRegister(
1778 new(zone()) LUint32ToDouble(UseRegister(instr->value()), temp)); 1866 new(zone()) LUint32ToDouble(UseRegister(instr->value()), temp));
1779 } else { 1867 } else {
1780 ASSERT(to.IsDouble()); 1868 ASSERT(to.IsDouble());
1781 LOperand* value = Use(instr->value()); 1869 LOperand* value = Use(instr->value());
1782 return DefineAsRegister(new(zone()) LInteger32ToDouble(value)); 1870 return DefineAsRegister(new(zone()) LInteger32ToDouble(value));
1783 } 1871 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1840 ASSERT(input_rep.IsSmiOrTagged()); 1928 ASSERT(input_rep.IsSmiOrTagged());
1841 // Register allocator doesn't (yet) support allocation of double 1929 // Register allocator doesn't (yet) support allocation of double
1842 // temps. Reserve xmm1 explicitly. 1930 // temps. Reserve xmm1 explicitly.
1843 LClampTToUint8* result = new(zone()) LClampTToUint8(reg, 1931 LClampTToUint8* result = new(zone()) LClampTToUint8(reg,
1844 FixedTemp(xmm1)); 1932 FixedTemp(xmm1));
1845 return AssignEnvironment(DefineSameAsFirst(result)); 1933 return AssignEnvironment(DefineSameAsFirst(result));
1846 } 1934 }
1847 } 1935 }
1848 1936
1849 1937
1938 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) {
1939 HValue* value = instr->value();
1940 ASSERT(value->representation().IsDouble());
1941 return DefineAsRegister(new(zone()) LDoubleBits(UseRegister(value)));
1942 }
1943
1944
1945 LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) {
1946 LOperand* lo = UseRegister(instr->lo());
1947 LOperand* hi = UseRegister(instr->hi());
1948 return DefineAsRegister(new(zone()) LConstructDouble(hi, lo));
1949 }
1950
1951
1850 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { 1952 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
1851 LOperand* context = info()->IsStub() ? UseFixed(instr->context(), rsi) : NULL; 1953 LOperand* context = info()->IsStub() ? UseFixed(instr->context(), rsi) : NULL;
1852 LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count()); 1954 LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count());
1853 return new(zone()) LReturn( 1955 return new(zone()) LReturn(
1854 UseFixed(instr->value(), rax), context, parameter_count); 1956 UseFixed(instr->value(), rax), context, parameter_count);
1855 } 1957 }
1856 1958
1857 1959
1858 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { 1960 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
1859 Representation r = instr->representation(); 1961 Representation r = instr->representation();
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
2121 ASSERT(!needs_write_barrier_for_map); 2223 ASSERT(!needs_write_barrier_for_map);
2122 obj = UseRegisterOrConstant(instr->object()); 2224 obj = UseRegisterOrConstant(instr->object());
2123 } else { 2225 } else {
2124 obj = needs_write_barrier_for_map 2226 obj = needs_write_barrier_for_map
2125 ? UseRegister(instr->object()) 2227 ? UseRegister(instr->object())
2126 : UseRegisterAtStart(instr->object()); 2228 : UseRegisterAtStart(instr->object());
2127 } 2229 }
2128 2230
2129 bool can_be_constant = instr->value()->IsConstant() && 2231 bool can_be_constant = instr->value()->IsConstant() &&
2130 HConstant::cast(instr->value())->NotInNewSpace() && 2232 HConstant::cast(instr->value())->NotInNewSpace() &&
2131 !(FLAG_track_double_fields && instr->field_representation().IsDouble()); 2233 !instr->field_representation().IsDouble();
2132 2234
2133 LOperand* val; 2235 LOperand* val;
2134 if (needs_write_barrier) { 2236 if (needs_write_barrier) {
2135 val = UseTempRegister(instr->value()); 2237 val = UseTempRegister(instr->value());
2136 } else if (is_external_location) { 2238 } else if (is_external_location) {
2137 val = UseFixed(instr->value(), rax); 2239 val = UseFixed(instr->value(), rax);
2138 } else if (can_be_constant) { 2240 } else if (can_be_constant) {
2139 val = UseRegisterOrConstant(instr->value()); 2241 val = UseRegisterOrConstant(instr->value());
2140 } else if (FLAG_track_fields && instr->field_representation().IsSmi()) { 2242 } else if (instr->field_representation().IsSmi()) {
2141 val = UseRegister(instr->value()); 2243 val = UseRegister(instr->value());
2142 } else if (FLAG_track_double_fields && 2244 } else if (instr->field_representation().IsDouble()) {
2143 instr->field_representation().IsDouble()) {
2144 val = UseRegisterAtStart(instr->value()); 2245 val = UseRegisterAtStart(instr->value());
2145 } else { 2246 } else {
2146 val = UseRegister(instr->value()); 2247 val = UseRegister(instr->value());
2147 } 2248 }
2148 2249
2149 // We only need a scratch register if we have a write barrier or we 2250 // We only need a scratch register if we have a write barrier or we
2150 // have a store into the properties array (not in-object-property). 2251 // have a store into the properties array (not in-object-property).
2151 LOperand* temp = (!is_in_object || needs_write_barrier || 2252 LOperand* temp = (!is_in_object || needs_write_barrier ||
2152 needs_write_barrier_for_map) ? TempRegister() : NULL; 2253 needs_write_barrier_for_map) ? TempRegister() : NULL;
2153 2254
2154 LStoreNamedField* result = new(zone()) LStoreNamedField(obj, val, temp); 2255 LStoreNamedField* result = new(zone()) LStoreNamedField(obj, val, temp);
2155 if (FLAG_track_heap_object_fields && 2256 if (instr->field_representation().IsHeapObject()) {
2156 instr->field_representation().IsHeapObject()) {
2157 if (!instr->value()->type().IsHeapObject()) { 2257 if (!instr->value()->type().IsHeapObject()) {
2158 return AssignEnvironment(result); 2258 return AssignEnvironment(result);
2159 } 2259 }
2160 } 2260 }
2161 return result; 2261 return result;
2162 } 2262 }
2163 2263
2164 2264
2165 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { 2265 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
2166 LOperand* context = UseFixed(instr->context(), rsi); 2266 LOperand* context = UseFixed(instr->context(), rsi);
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
2333 2433
2334 2434
2335 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch( 2435 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch(
2336 HIsConstructCallAndBranch* instr) { 2436 HIsConstructCallAndBranch* instr) {
2337 return new(zone()) LIsConstructCallAndBranch(TempRegister()); 2437 return new(zone()) LIsConstructCallAndBranch(TempRegister());
2338 } 2438 }
2339 2439
2340 2440
2341 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { 2441 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
2342 instr->ReplayEnvironment(current_block_->last_environment()); 2442 instr->ReplayEnvironment(current_block_->last_environment());
2343
2344 // If there is an instruction pending deoptimization environment create a
2345 // lazy bailout instruction to capture the environment.
2346 if (pending_deoptimization_ast_id_ == instr->ast_id()) {
2347 LLazyBailout* lazy_bailout = new(zone()) LLazyBailout;
2348 LInstruction* result = AssignEnvironment(lazy_bailout);
2349 // Store the lazy deopt environment with the instruction if needed. Right
2350 // now it is only used for LInstanceOfKnownGlobal.
2351 instruction_pending_deoptimization_environment_->
2352 SetDeferredLazyDeoptimizationEnvironment(result->environment());
2353 instruction_pending_deoptimization_environment_ = NULL;
2354 pending_deoptimization_ast_id_ = BailoutId::None();
2355 return result;
2356 }
2357
2358 return NULL; 2443 return NULL;
2359 } 2444 }
2360 2445
2361 2446
2362 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { 2447 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
2363 info()->MarkAsDeferredCalling(); 2448 info()->MarkAsDeferredCalling();
2364 if (instr->is_function_entry()) { 2449 if (instr->is_function_entry()) {
2365 LOperand* context = UseFixed(instr->context(), rsi); 2450 LOperand* context = UseFixed(instr->context(), rsi);
2366 return MarkAsCall(new(zone()) LStackCheck(context), instr); 2451 return MarkAsCall(new(zone()) LStackCheck(context), instr);
2367 } else { 2452 } else {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2436 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { 2521 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
2437 LOperand* object = UseRegister(instr->object()); 2522 LOperand* object = UseRegister(instr->object());
2438 LOperand* index = UseTempRegister(instr->index()); 2523 LOperand* index = UseTempRegister(instr->index());
2439 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); 2524 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index));
2440 } 2525 }
2441 2526
2442 2527
2443 } } // namespace v8::internal 2528 } } // namespace v8::internal
2444 2529
2445 #endif // V8_TARGET_ARCH_X64 2530 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/lithium-x64.h ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698