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

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

Issue 6881003: Prevent deopt when assigning double values to typed arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixes to make ia32 tests run Created 9 years, 8 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 786 matching lines...) Expand 10 before | Expand all | Expand 10 after
797 } 797 }
798 798
799 799
800 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { 800 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
801 return AssignEnvironment(new LDeoptimize); 801 return AssignEnvironment(new LDeoptimize);
802 } 802 }
803 803
804 804
805 LInstruction* LChunkBuilder::DoBit(Token::Value op, 805 LInstruction* LChunkBuilder::DoBit(Token::Value op,
806 HBitwiseBinaryOperation* instr) { 806 HBitwiseBinaryOperation* instr) {
807 if (instr->representation().IsInteger32()) { 807 if (instr->representation().IsInteger()) {
808 ASSERT(instr->left()->representation().IsInteger32()); 808 ASSERT(instr->left()->representation().IsInteger());
809 ASSERT(instr->right()->representation().IsInteger32()); 809 ASSERT(instr->right()->representation().IsInteger());
810 810
811 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); 811 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
812 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand()); 812 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand());
813 return DefineSameAsFirst(new LBitI(op, left, right)); 813 return DefineSameAsFirst(new LBitI(op, left, right));
814 } else { 814 } else {
815 ASSERT(instr->representation().IsTagged()); 815 ASSERT(instr->representation().IsTagged());
816 ASSERT(instr->left()->representation().IsTagged()); 816 ASSERT(instr->left()->representation().IsTagged());
817 ASSERT(instr->right()->representation().IsTagged()); 817 ASSERT(instr->right()->representation().IsTagged());
818 818
819 LOperand* left = UseFixed(instr->left(), edx); 819 LOperand* left = UseFixed(instr->left(), edx);
820 LOperand* right = UseFixed(instr->right(), eax); 820 LOperand* right = UseFixed(instr->right(), eax);
821 LArithmeticT* result = new LArithmeticT(op, left, right); 821 LArithmeticT* result = new LArithmeticT(op, left, right);
822 return MarkAsCall(DefineFixed(result, eax), instr); 822 return MarkAsCall(DefineFixed(result, eax), instr);
823 } 823 }
824 } 824 }
825 825
826 826
827 LInstruction* LChunkBuilder::DoShift(Token::Value op, 827 LInstruction* LChunkBuilder::DoShift(Token::Value op,
828 HBitwiseBinaryOperation* instr) { 828 HBitwiseBinaryOperation* instr) {
829 if (instr->representation().IsTagged()) { 829 if (instr->representation().IsTagged()) {
830 ASSERT(instr->left()->representation().IsTagged()); 830 ASSERT(instr->left()->representation().IsTagged());
831 ASSERT(instr->right()->representation().IsTagged()); 831 ASSERT(instr->right()->representation().IsTagged());
832 832
833 LOperand* left = UseFixed(instr->left(), edx); 833 LOperand* left = UseFixed(instr->left(), edx);
834 LOperand* right = UseFixed(instr->right(), eax); 834 LOperand* right = UseFixed(instr->right(), eax);
835 LArithmeticT* result = new LArithmeticT(op, left, right); 835 LArithmeticT* result = new LArithmeticT(op, left, right);
836 return MarkAsCall(DefineFixed(result, eax), instr); 836 return MarkAsCall(DefineFixed(result, eax), instr);
837 } 837 }
838 838
839 ASSERT(instr->representation().IsInteger32()); 839 ASSERT(instr->representation().IsInteger());
840 ASSERT(instr->OperandAt(0)->representation().IsInteger32()); 840 ASSERT(instr->OperandAt(0)->representation().IsInteger32X());
841 ASSERT(instr->OperandAt(1)->representation().IsInteger32()); 841 ASSERT(instr->OperandAt(1)->representation().IsInteger32X());
842 LOperand* left = UseRegisterAtStart(instr->OperandAt(0)); 842 LOperand* left = UseRegisterAtStart(instr->OperandAt(0));
843 843
844 HValue* right_value = instr->OperandAt(1); 844 HValue* right_value = instr->OperandAt(1);
845 LOperand* right = NULL; 845 LOperand* right = NULL;
846 int constant_value = 0; 846 int constant_value = 0;
847 if (right_value->IsConstant()) { 847 if (right_value->IsConstant()) {
848 HConstant* constant = HConstant::cast(right_value); 848 HConstant* constant = HConstant::cast(right_value);
849 right = chunk_->DefineConstantOperand(constant); 849 right = chunk_->DefineConstantOperand(constant);
850 constant_value = constant->Integer32Value() & 0x1f; 850 constant_value = constant->Integer32Value() & 0x1f;
851 } else { 851 } else {
852 right = UseFixed(right_value, ecx); 852 right = UseFixed(right_value, ecx);
853 } 853 }
854 854
855 // Shift operations can only deoptimize if we do a logical shift 855 // Shift operations can only deoptimize if we do a logical shift
856 // by 0 and the result cannot be truncated to int32. 856 // by 0 and the result cannot be truncated to int32.
857 bool can_deopt = (op == Token::SHR && constant_value == 0); 857 bool can_deopt = op == Token::SHR &&
858 if (can_deopt) { 858 constant_value == 0 &&
859 bool can_truncate = true; 859 !instr->representation().Equals(Representation::TruncatedInteger32());
860 for (int i = 0; i < instr->uses()->length(); i++) {
861 if (!instr->uses()->at(i)->CheckFlag(HValue::kTruncatingToInt32)) {
862 can_truncate = false;
863 break;
864 }
865 }
866 can_deopt = !can_truncate;
867 }
868 860
869 LShiftI* result = new LShiftI(op, left, right, can_deopt); 861 LShiftI* result = new LShiftI(op, left, right, can_deopt);
870 return can_deopt 862 return can_deopt
871 ? AssignEnvironment(DefineSameAsFirst(result)) 863 ? AssignEnvironment(DefineSameAsFirst(result))
872 : DefineSameAsFirst(result); 864 : DefineSameAsFirst(result);
873 } 865 }
874 866
875 867
876 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, 868 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op,
877 HArithmeticBinaryOperation* instr) { 869 HArithmeticBinaryOperation* instr) {
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1046 1038
1047 return new LClassOfTestAndBranch(UseTempRegister(compare->value()), 1039 return new LClassOfTestAndBranch(UseTempRegister(compare->value()),
1048 TempRegister(), 1040 TempRegister(),
1049 TempRegister()); 1041 TempRegister());
1050 } else if (v->IsCompare()) { 1042 } else if (v->IsCompare()) {
1051 HCompare* compare = HCompare::cast(v); 1043 HCompare* compare = HCompare::cast(v);
1052 Token::Value op = compare->token(); 1044 Token::Value op = compare->token();
1053 HValue* left = compare->left(); 1045 HValue* left = compare->left();
1054 HValue* right = compare->right(); 1046 HValue* right = compare->right();
1055 Representation r = compare->GetInputRepresentation(); 1047 Representation r = compare->GetInputRepresentation();
1056 if (r.IsInteger32()) { 1048 if (r.IsInteger()) {
1057 ASSERT(left->representation().IsInteger32()); 1049 ASSERT(left->representation().IsInteger());
1058 ASSERT(right->representation().IsInteger32()); 1050 ASSERT(right->representation().IsInteger());
1059 1051
1060 return new LCmpIDAndBranch(UseRegisterAtStart(left), 1052 return new LCmpIDAndBranch(UseRegisterAtStart(left),
1061 UseOrConstantAtStart(right)); 1053 UseOrConstantAtStart(right));
1062 } else if (r.IsDouble()) { 1054 } else if (r.IsDouble()) {
1063 ASSERT(left->representation().IsDouble()); 1055 ASSERT(left->representation().IsDouble());
1064 ASSERT(right->representation().IsDouble()); 1056 ASSERT(right->representation().IsDouble());
1065 1057
1066 return new LCmpIDAndBranch(UseRegisterAtStart(left), 1058 return new LCmpIDAndBranch(UseRegisterAtStart(left),
1067 UseRegisterAtStart(right)); 1059 UseRegisterAtStart(right));
1068 } else { 1060 } else {
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
1342 return DoShift(Token::SHL, instr); 1334 return DoShift(Token::SHL, instr);
1343 } 1335 }
1344 1336
1345 1337
1346 LInstruction* LChunkBuilder::DoBitAnd(HBitAnd* instr) { 1338 LInstruction* LChunkBuilder::DoBitAnd(HBitAnd* instr) {
1347 return DoBit(Token::BIT_AND, instr); 1339 return DoBit(Token::BIT_AND, instr);
1348 } 1340 }
1349 1341
1350 1342
1351 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { 1343 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) {
1352 ASSERT(instr->value()->representation().IsInteger32()); 1344 ASSERT(instr->value()->representation().IsInteger());
1353 ASSERT(instr->representation().IsInteger32()); 1345 ASSERT(instr->representation().IsInteger32X());
1354 LOperand* input = UseRegisterAtStart(instr->value()); 1346 LOperand* input = UseRegisterAtStart(instr->value());
1355 LBitNotI* result = new LBitNotI(input); 1347 LBitNotI* result = new LBitNotI(input);
1356 return DefineSameAsFirst(result); 1348 return DefineSameAsFirst(result);
1357 } 1349 }
1358 1350
1359 1351
1360 LInstruction* LChunkBuilder::DoBitOr(HBitOr* instr) { 1352 LInstruction* LChunkBuilder::DoBitOr(HBitOr* instr) {
1361 return DoBit(Token::BIT_OR, instr); 1353 return DoBit(Token::BIT_OR, instr);
1362 } 1354 }
1363 1355
1364 1356
1365 LInstruction* LChunkBuilder::DoBitXor(HBitXor* instr) { 1357 LInstruction* LChunkBuilder::DoBitXor(HBitXor* instr) {
1366 return DoBit(Token::BIT_XOR, instr); 1358 return DoBit(Token::BIT_XOR, instr);
1367 } 1359 }
1368 1360
1369 1361
1370 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { 1362 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
1371 if (instr->representation().IsDouble()) { 1363 if (instr->representation().IsDouble()) {
1372 return DoArithmeticD(Token::DIV, instr); 1364 return DoArithmeticD(Token::DIV, instr);
1373 } else if (instr->representation().IsInteger32()) { 1365 } else if (instr->representation().IsInteger()) {
1366 ASSERT(instr->representation().IsInteger32X());
1374 // The temporary operand is necessary to ensure that right is not allocated 1367 // The temporary operand is necessary to ensure that right is not allocated
1375 // into edx. 1368 // into edx.
1376 LOperand* temp = FixedTemp(edx); 1369 LOperand* temp = FixedTemp(edx);
1377 LOperand* dividend = UseFixed(instr->left(), eax); 1370 LOperand* dividend = UseFixed(instr->left(), eax);
1378 LOperand* divisor = UseRegister(instr->right()); 1371 LOperand* divisor = UseRegister(instr->right());
1379 LDivI* result = new LDivI(dividend, divisor, temp); 1372 LDivI* result = new LDivI(dividend, divisor, temp);
1380 return AssignEnvironment(DefineFixed(result, eax)); 1373 return AssignEnvironment(DefineFixed(result, eax));
1381 } else { 1374 } else {
1382 ASSERT(instr->representation().IsTagged()); 1375 ASSERT(instr->representation().IsTagged());
1383 return DoArithmeticT(Token::DIV, instr); 1376 return DoArithmeticT(Token::DIV, instr);
1384 } 1377 }
1385 } 1378 }
1386 1379
1387 1380
1388 LInstruction* LChunkBuilder::DoMod(HMod* instr) { 1381 LInstruction* LChunkBuilder::DoMod(HMod* instr) {
1389 if (instr->representation().IsInteger32()) { 1382 if (instr->representation().IsInteger32X()) {
1390 ASSERT(instr->left()->representation().IsInteger32()); 1383 ASSERT(instr->left()->representation().IsInteger());
1391 ASSERT(instr->right()->representation().IsInteger32()); 1384 ASSERT(instr->right()->representation().IsInteger());
1392 1385
1393 LInstruction* result; 1386 LInstruction* result;
1394 if (instr->HasPowerOf2Divisor()) { 1387 if (instr->HasPowerOf2Divisor()) {
1395 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); 1388 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero));
1396 LOperand* value = UseRegisterAtStart(instr->left()); 1389 LOperand* value = UseRegisterAtStart(instr->left());
1397 LModI* mod = new LModI(value, UseOrConstant(instr->right()), NULL); 1390 LModI* mod = new LModI(value, UseOrConstant(instr->right()), NULL);
1398 result = DefineSameAsFirst(mod); 1391 result = DefineSameAsFirst(mod);
1399 } else { 1392 } else {
1400 // The temporary operand is necessary to ensure that right is 1393 // The temporary operand is necessary to ensure that right is
1401 // not allocated into edx. 1394 // not allocated into edx.
(...skipping 17 matching lines...) Expand all
1419 // TODO(fschneider): Allow any register as input registers. 1412 // TODO(fschneider): Allow any register as input registers.
1420 LOperand* left = UseFixedDouble(instr->left(), xmm2); 1413 LOperand* left = UseFixedDouble(instr->left(), xmm2);
1421 LOperand* right = UseFixedDouble(instr->right(), xmm1); 1414 LOperand* right = UseFixedDouble(instr->right(), xmm1);
1422 LArithmeticD* result = new LArithmeticD(Token::MOD, left, right); 1415 LArithmeticD* result = new LArithmeticD(Token::MOD, left, right);
1423 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); 1416 return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
1424 } 1417 }
1425 } 1418 }
1426 1419
1427 1420
1428 LInstruction* LChunkBuilder::DoMul(HMul* instr) { 1421 LInstruction* LChunkBuilder::DoMul(HMul* instr) {
1429 if (instr->representation().IsInteger32()) { 1422 if (instr->representation().IsInteger32X()) {
1430 ASSERT(instr->left()->representation().IsInteger32()); 1423 ASSERT(instr->left()->representation().IsInteger());
1431 ASSERT(instr->right()->representation().IsInteger32()); 1424 ASSERT(instr->right()->representation().IsInteger());
1432 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); 1425 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
1433 LOperand* right = UseOrConstant(instr->MostConstantOperand()); 1426 LOperand* right = UseOrConstant(instr->MostConstantOperand());
1434 LOperand* temp = NULL; 1427 LOperand* temp = NULL;
1435 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) { 1428 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1436 temp = TempRegister(); 1429 temp = TempRegister();
1437 } 1430 }
1438 LMulI* mul = new LMulI(left, right, temp); 1431 LMulI* mul = new LMulI(left, right, temp);
1439 return AssignEnvironment(DefineSameAsFirst(mul)); 1432 return AssignEnvironment(DefineSameAsFirst(mul));
1440 } else if (instr->representation().IsDouble()) { 1433 } else if (instr->representation().IsDouble()) {
1441 return DoArithmeticD(Token::MUL, instr); 1434 return DoArithmeticD(Token::MUL, instr);
1442 } else { 1435 } else {
1443 ASSERT(instr->representation().IsTagged()); 1436 ASSERT(instr->representation().IsTagged());
1444 return DoArithmeticT(Token::MUL, instr); 1437 return DoArithmeticT(Token::MUL, instr);
1445 } 1438 }
1446 } 1439 }
1447 1440
1448 1441
1449 LInstruction* LChunkBuilder::DoSub(HSub* instr) { 1442 LInstruction* LChunkBuilder::DoSub(HSub* instr) {
1450 if (instr->representation().IsInteger32()) { 1443 if (instr->representation().IsInteger32X()) {
1451 ASSERT(instr->left()->representation().IsInteger32()); 1444 ASSERT(instr->left()->representation().IsInteger());
1452 ASSERT(instr->right()->representation().IsInteger32()); 1445 ASSERT(instr->right()->representation().IsInteger());
1453 LOperand* left = UseRegisterAtStart(instr->left()); 1446 LOperand* left = UseRegisterAtStart(instr->left());
1454 LOperand* right = UseOrConstantAtStart(instr->right()); 1447 LOperand* right = UseOrConstantAtStart(instr->right());
1455 LSubI* sub = new LSubI(left, right); 1448 LSubI* sub = new LSubI(left, right);
1456 LInstruction* result = DefineSameAsFirst(sub); 1449 LInstruction* result = DefineSameAsFirst(sub);
1457 if (instr->CheckFlag(HValue::kCanOverflow)) { 1450 if (instr->CheckFlag(HValue::kCanOverflow)) {
1458 result = AssignEnvironment(result); 1451 result = AssignEnvironment(result);
1459 } 1452 }
1460 return result; 1453 return result;
1461 } else if (instr->representation().IsDouble()) { 1454 } else if (instr->representation().IsDouble()) {
1462 return DoArithmeticD(Token::SUB, instr); 1455 return DoArithmeticD(Token::SUB, instr);
1463 } else { 1456 } else {
1464 ASSERT(instr->representation().IsTagged()); 1457 ASSERT(instr->representation().IsTagged());
1465 return DoArithmeticT(Token::SUB, instr); 1458 return DoArithmeticT(Token::SUB, instr);
1466 } 1459 }
1467 } 1460 }
1468 1461
1469 1462
1470 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { 1463 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
1471 if (instr->representation().IsInteger32()) { 1464 if (instr->representation().IsInteger32X()) {
1472 ASSERT(instr->left()->representation().IsInteger32()); 1465 ASSERT(instr->left()->representation().IsInteger());
1473 ASSERT(instr->right()->representation().IsInteger32()); 1466 ASSERT(instr->right()->representation().IsInteger());
1474 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); 1467 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
1475 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand()); 1468 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand());
1476 LAddI* add = new LAddI(left, right); 1469 LAddI* add = new LAddI(left, right);
1477 LInstruction* result = DefineSameAsFirst(add); 1470 LInstruction* result = DefineSameAsFirst(add);
1478 if (instr->CheckFlag(HValue::kCanOverflow)) { 1471 if (instr->CheckFlag(HValue::kCanOverflow)) {
1479 result = AssignEnvironment(result); 1472 result = AssignEnvironment(result);
1480 } 1473 }
1481 return result; 1474 return result;
1482 } else if (instr->representation().IsDouble()) { 1475 } else if (instr->representation().IsDouble()) {
1483 return DoArithmeticD(Token::ADD, instr); 1476 return DoArithmeticD(Token::ADD, instr);
(...skipping 16 matching lines...) Expand all
1500 UseFixed(instr->right(), eax); 1493 UseFixed(instr->right(), eax);
1501 LPower* result = new LPower(left, right); 1494 LPower* result = new LPower(left, right);
1502 return MarkAsCall(DefineFixedDouble(result, xmm3), instr, 1495 return MarkAsCall(DefineFixedDouble(result, xmm3), instr,
1503 CAN_DEOPTIMIZE_EAGERLY); 1496 CAN_DEOPTIMIZE_EAGERLY);
1504 } 1497 }
1505 1498
1506 1499
1507 LInstruction* LChunkBuilder::DoCompare(HCompare* instr) { 1500 LInstruction* LChunkBuilder::DoCompare(HCompare* instr) {
1508 Token::Value op = instr->token(); 1501 Token::Value op = instr->token();
1509 Representation r = instr->GetInputRepresentation(); 1502 Representation r = instr->GetInputRepresentation();
1510 if (r.IsInteger32()) { 1503 if (r.IsInteger32X()) {
1511 ASSERT(instr->left()->representation().IsInteger32()); 1504 ASSERT(instr->left()->representation().IsInteger());
1512 ASSERT(instr->right()->representation().IsInteger32()); 1505 ASSERT(instr->right()->representation().IsInteger());
1513 LOperand* left = UseRegisterAtStart(instr->left()); 1506 LOperand* left = UseRegisterAtStart(instr->left());
1514 LOperand* right = UseOrConstantAtStart(instr->right()); 1507 LOperand* right = UseOrConstantAtStart(instr->right());
1515 return DefineAsRegister(new LCmpID(left, right)); 1508 return DefineAsRegister(new LCmpID(left, right));
1516 } else if (r.IsDouble()) { 1509 } else if (r.IsDouble()) {
1517 ASSERT(instr->left()->representation().IsDouble()); 1510 ASSERT(instr->left()->representation().IsDouble());
1518 ASSERT(instr->right()->representation().IsDouble()); 1511 ASSERT(instr->right()->representation().IsDouble());
1519 LOperand* left = UseRegisterAtStart(instr->left()); 1512 LOperand* left = UseRegisterAtStart(instr->left());
1520 LOperand* right = UseRegisterAtStart(instr->right()); 1513 LOperand* right = UseRegisterAtStart(instr->right());
1521 return DefineAsRegister(new LCmpID(left, right)); 1514 return DefineAsRegister(new LCmpID(left, right));
1522 } else { 1515 } else {
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1645 1638
1646 LInstruction* LChunkBuilder::DoChange(HChange* instr) { 1639 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1647 Representation from = instr->from(); 1640 Representation from = instr->from();
1648 Representation to = instr->to(); 1641 Representation to = instr->to();
1649 if (from.IsTagged()) { 1642 if (from.IsTagged()) {
1650 if (to.IsDouble()) { 1643 if (to.IsDouble()) {
1651 LOperand* value = UseRegister(instr->value()); 1644 LOperand* value = UseRegister(instr->value());
1652 LNumberUntagD* res = new LNumberUntagD(value); 1645 LNumberUntagD* res = new LNumberUntagD(value);
1653 return AssignEnvironment(DefineAsRegister(res)); 1646 return AssignEnvironment(DefineAsRegister(res));
1654 } else { 1647 } else {
1655 ASSERT(to.IsInteger32()); 1648 ASSERT(to.IsInteger());
1656 LOperand* value = UseRegister(instr->value()); 1649 LOperand* value = UseRegister(instr->value());
1657 bool needs_check = !instr->value()->type().IsSmi(); 1650 bool needs_check = !instr->value()->type().IsSmi();
1651 bool needs_temp = to.IsClampedRoundedInteger8() ||
1652 (!(CpuFeatures::IsSupported(SSE3) && to.IsTruncatedInteger32()));
1653 ToIRoundingMode rounding_mode(RepresentationToRoundingMode(to));
1658 if (needs_check) { 1654 if (needs_check) {
1659 LOperand* xmm_temp = 1655 LOperand* xmm_temp = needs_temp ? FixedTemp(xmm1) : NULL;
1660 (instr->CanTruncateToInt32() && CpuFeatures::IsSupported(SSE3)) 1656 LTaggedToI* res = new LTaggedToI(value, xmm_temp, rounding_mode);
1661 ? NULL
1662 : FixedTemp(xmm1);
1663 LTaggedToI* res = new LTaggedToI(value, xmm_temp);
1664 return AssignEnvironment(DefineSameAsFirst(res)); 1657 return AssignEnvironment(DefineSameAsFirst(res));
1665 } else { 1658 } else {
1666 return DefineSameAsFirst(new LSmiUntag(value, needs_check)); 1659 bool should_clamp = to.IsClampedRoundedInteger8();
1660 return DefineSameAsFirst(new LSmiUntag(value,
1661 false,
1662 should_clamp));
1667 } 1663 }
1668 } 1664 }
1669 } else if (from.IsDouble()) { 1665 } else if (from.IsDouble()) {
1670 if (to.IsTagged()) { 1666 if (to.IsTagged()) {
1671 LOperand* value = UseRegister(instr->value()); 1667 LOperand* value = UseRegister(instr->value());
1672 LOperand* temp = TempRegister(); 1668 LOperand* temp = TempRegister();
1673 1669
1674 // Make sure that temp and result_temp are different registers. 1670 // Make sure that temp and result_temp are different registers.
1675 LUnallocated* result_temp = TempRegister(); 1671 LUnallocated* result_temp = TempRegister();
1676 LNumberTagD* result = new LNumberTagD(value, temp); 1672 LNumberTagD* result = new LNumberTagD(value, temp);
1677 return AssignPointerMap(Define(result, result_temp)); 1673 return AssignPointerMap(Define(result, result_temp));
1678 } else { 1674 } else {
1679 ASSERT(to.IsInteger32()); 1675 ASSERT(to.IsInteger());
1680 bool needs_temp = instr->CanTruncateToInt32() && 1676 ToIRoundingMode rounding_mode(RepresentationToRoundingMode(to));
1681 !CpuFeatures::IsSupported(SSE3); 1677 bool needs_temp = to.IsClampedRoundedInteger8() ||
1678 (!(CpuFeatures::IsSupported(SSE3) && to.IsTruncatedInteger32()));
1682 LOperand* value = needs_temp ? 1679 LOperand* value = needs_temp ?
1683 UseTempRegister(instr->value()) : UseRegister(instr->value()); 1680 UseTempRegister(instr->value()) : UseRegister(instr->value());
1684 LOperand* temp = needs_temp ? TempRegister() : NULL; 1681 LOperand* temp = needs_temp ? TempRegister() : NULL;
1685 return AssignEnvironment(DefineAsRegister(new LDoubleToI(value, temp))); 1682 return AssignEnvironment(DefineAsRegister(new LDoubleToI(value,
1683 temp,
1684 rounding_mode)));
1686 } 1685 }
1687 } else if (from.IsInteger32()) { 1686 } else if (from.IsInteger()) {
1688 if (to.IsTagged()) { 1687 if (to.IsTagged()) {
1689 HValue* val = instr->value(); 1688 HValue* val = instr->value();
1690 LOperand* value = UseRegister(val); 1689 LOperand* value = UseRegister(val);
1691 if (val->HasRange() && val->range()->IsInSmiRange()) { 1690 if (val->HasRange() && val->range()->IsInSmiRange()) {
1692 return DefineSameAsFirst(new LSmiTag(value)); 1691 return DefineSameAsFirst(new LSmiTag(value));
1693 } else { 1692 } else {
1694 LNumberTagI* result = new LNumberTagI(value); 1693 LNumberTagI* result = new LNumberTagI(value);
1695 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); 1694 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
1696 } 1695 }
1696 } else if (to.IsClampedRoundedInteger8()) {
1697 return DefineFixed(new LInteger32ToClamped(
1698 UseFixed(instr->value(), eax)), eax);
1697 } else { 1699 } else {
1698 ASSERT(to.IsDouble()); 1700 ASSERT(to.IsDouble());
1699 return DefineAsRegister(new LInteger32ToDouble(Use(instr->value()))); 1701 return DefineAsRegister(new LInteger32ToDouble(Use(instr->value())));
1700 } 1702 }
1701 } 1703 }
1702 UNREACHABLE(); 1704 UNREACHABLE();
1703 return NULL; 1705 return NULL;
1704 } 1706 }
1705 1707
1706 1708
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1744 } 1746 }
1745 1747
1746 1748
1747 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { 1749 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
1748 return new LReturn(UseFixed(instr->value(), eax)); 1750 return new LReturn(UseFixed(instr->value(), eax));
1749 } 1751 }
1750 1752
1751 1753
1752 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { 1754 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
1753 Representation r = instr->representation(); 1755 Representation r = instr->representation();
1754 if (r.IsInteger32()) { 1756 if (r.IsInteger()) {
1755 return DefineAsRegister(new LConstantI); 1757 return DefineAsRegister(new LConstantI);
1756 } else if (r.IsDouble()) { 1758 } else if (r.IsDouble()) {
1757 double value = instr->DoubleValue(); 1759 double value = instr->DoubleValue();
1758 LOperand* temp = (BitCast<uint64_t, double>(value) != 0) 1760 LOperand* temp = (BitCast<uint64_t, double>(value) != 0)
1759 ? TempRegister() 1761 ? TempRegister()
1760 : NULL; 1762 : NULL;
1761 return DefineAsRegister(new LConstantD(temp)); 1763 return DefineAsRegister(new LConstantD(temp));
1762 } else if (r.IsTagged()) { 1764 } else if (r.IsTagged()) {
1763 return DefineAsRegister(new LConstantT); 1765 return DefineAsRegister(new LConstantT);
1764 } else { 1766 } else {
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1871 LInstruction* LChunkBuilder::DoLoadExternalArrayPointer( 1873 LInstruction* LChunkBuilder::DoLoadExternalArrayPointer(
1872 HLoadExternalArrayPointer* instr) { 1874 HLoadExternalArrayPointer* instr) {
1873 LOperand* input = UseRegisterAtStart(instr->value()); 1875 LOperand* input = UseRegisterAtStart(instr->value());
1874 return DefineAsRegister(new LLoadExternalArrayPointer(input)); 1876 return DefineAsRegister(new LLoadExternalArrayPointer(input));
1875 } 1877 }
1876 1878
1877 1879
1878 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( 1880 LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
1879 HLoadKeyedFastElement* instr) { 1881 HLoadKeyedFastElement* instr) {
1880 ASSERT(instr->representation().IsTagged()); 1882 ASSERT(instr->representation().IsTagged());
1881 ASSERT(instr->key()->representation().IsInteger32()); 1883 ASSERT(instr->key()->representation().IsInteger32X());
1882 LOperand* obj = UseRegisterAtStart(instr->object()); 1884 LOperand* obj = UseRegisterAtStart(instr->object());
1883 LOperand* key = UseRegisterAtStart(instr->key()); 1885 LOperand* key = UseRegisterAtStart(instr->key());
1884 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key); 1886 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
1885 return AssignEnvironment(DefineSameAsFirst(result)); 1887 return AssignEnvironment(DefineSameAsFirst(result));
1886 } 1888 }
1887 1889
1888 1890
1889 LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( 1891 LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
1890 HLoadKeyedSpecializedArrayElement* instr) { 1892 HLoadKeyedSpecializedArrayElement* instr) {
1891 ExternalArrayType array_type = instr->array_type(); 1893 ExternalArrayType array_type = instr->array_type();
1892 Representation representation(instr->representation()); 1894 Representation representation(instr->representation());
1893 ASSERT((representation.IsInteger32() && array_type != kExternalFloatArray) || 1895 ASSERT((representation.IsInteger32X() && array_type != kExternalFloatArray) ||
1894 (representation.IsDouble() && array_type == kExternalFloatArray)); 1896 (representation.IsDouble() && array_type == kExternalFloatArray));
1895 ASSERT(instr->key()->representation().IsInteger32()); 1897 ASSERT(instr->key()->representation().IsInteger32X());
1896 LOperand* external_pointer = UseRegister(instr->external_pointer()); 1898 LOperand* external_pointer = UseRegister(instr->external_pointer());
1897 LOperand* key = UseRegister(instr->key()); 1899 LOperand* key = UseRegister(instr->key());
1898 LLoadKeyedSpecializedArrayElement* result = 1900 LLoadKeyedSpecializedArrayElement* result =
1899 new LLoadKeyedSpecializedArrayElement(external_pointer, 1901 new LLoadKeyedSpecializedArrayElement(external_pointer,
1900 key); 1902 key);
1901 LInstruction* load_instr = DefineAsRegister(result); 1903 LInstruction* load_instr = DefineAsRegister(result);
1902 // An unsigned int array load might overflow and cause a deopt, make sure it 1904 // An unsigned int array load might overflow and cause a deopt, make sure it
1903 // has an environment. 1905 // has an environment.
1904 return (array_type == kExternalUnsignedIntArray) 1906 return (array_type == kExternalUnsignedIntArray)
1905 ? AssignEnvironment(load_instr) 1907 ? AssignEnvironment(load_instr)
1906 : load_instr; 1908 : load_instr;
1907 } 1909 }
1908 1910
1909 1911
1910 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { 1912 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
1911 LOperand* context = UseFixed(instr->context(), esi); 1913 LOperand* context = UseFixed(instr->context(), esi);
1912 LOperand* object = UseFixed(instr->object(), edx); 1914 LOperand* object = UseFixed(instr->object(), edx);
1913 LOperand* key = UseFixed(instr->key(), eax); 1915 LOperand* key = UseFixed(instr->key(), eax);
1914 1916
1915 LLoadKeyedGeneric* result = new LLoadKeyedGeneric(context, object, key); 1917 LLoadKeyedGeneric* result = new LLoadKeyedGeneric(context, object, key);
1916 return MarkAsCall(DefineFixed(result, eax), instr); 1918 return MarkAsCall(DefineFixed(result, eax), instr);
1917 } 1919 }
1918 1920
1919 1921
1920 LInstruction* LChunkBuilder::DoStoreKeyedFastElement( 1922 LInstruction* LChunkBuilder::DoStoreKeyedFastElement(
1921 HStoreKeyedFastElement* instr) { 1923 HStoreKeyedFastElement* instr) {
1922 bool needs_write_barrier = instr->NeedsWriteBarrier(); 1924 bool needs_write_barrier = instr->NeedsWriteBarrier();
1923 ASSERT(instr->value()->representation().IsTagged()); 1925 ASSERT(instr->value()->representation().IsTagged());
1924 ASSERT(instr->object()->representation().IsTagged()); 1926 ASSERT(instr->object()->representation().IsTagged());
1925 ASSERT(instr->key()->representation().IsInteger32()); 1927 ASSERT(instr->key()->representation().IsInteger32X());
1926 1928
1927 LOperand* obj = UseTempRegister(instr->object()); 1929 LOperand* obj = UseTempRegister(instr->object());
1928 LOperand* val = needs_write_barrier 1930 LOperand* val = needs_write_barrier
1929 ? UseTempRegister(instr->value()) 1931 ? UseTempRegister(instr->value())
1930 : UseRegisterAtStart(instr->value()); 1932 : UseRegisterAtStart(instr->value());
1931 LOperand* key = needs_write_barrier 1933 LOperand* key = needs_write_barrier
1932 ? UseTempRegister(instr->key()) 1934 ? UseTempRegister(instr->key())
1933 : UseRegisterOrConstantAtStart(instr->key()); 1935 : UseRegisterOrConstantAtStart(instr->key());
1934 1936
1935 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val)); 1937 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val));
1936 } 1938 }
1937 1939
1938 1940
1939 LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement( 1941 LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
1940 HStoreKeyedSpecializedArrayElement* instr) { 1942 HStoreKeyedSpecializedArrayElement* instr) {
1941 Representation representation(instr->value()->representation()); 1943 Representation representation(instr->value()->representation());
1942 ExternalArrayType array_type = instr->array_type(); 1944 ExternalArrayType array_type = instr->array_type();
1943 ASSERT((representation.IsInteger32() && array_type != kExternalFloatArray) ||
1944 (representation.IsDouble() && array_type == kExternalFloatArray));
1945 ASSERT(instr->external_pointer()->representation().IsExternal()); 1945 ASSERT(instr->external_pointer()->representation().IsExternal());
1946 ASSERT(instr->key()->representation().IsInteger32()); 1946 ASSERT(instr->key()->representation().IsInteger32X());
1947 1947
1948 LOperand* external_pointer = UseRegister(instr->external_pointer()); 1948 LOperand* external_pointer = UseRegister(instr->external_pointer());
1949 LOperand* key = UseRegister(instr->key()); 1949 LOperand* key = UseRegister(instr->key());
1950 LOperand* temp = NULL;
1951
1952 if (array_type == kExternalPixelArray) {
1953 // The generated code for pixel array stores requires that the clamped value
1954 // is in a byte register. eax is an arbitrary choice to satisfy this
1955 // requirement.
1956 temp = FixedTemp(eax);
1957 }
1958 1950
1959 LOperand* val = NULL; 1951 LOperand* val = NULL;
1960 if (array_type == kExternalByteArray || 1952 if (array_type == kExternalByteArray ||
1961 array_type == kExternalUnsignedByteArray) { 1953 array_type == kExternalUnsignedByteArray ||
1954 array_type == kExternalPixelArray) {
1962 // We need a byte register in this case for the value. 1955 // We need a byte register in this case for the value.
1963 val = UseFixed(instr->value(), eax); 1956 val = UseFixed(instr->value(), eax);
1964 } else { 1957 } else {
1965 val = UseRegister(instr->value()); 1958 val = UseRegister(instr->value());
1966 } 1959 }
1967 1960
1968 return new LStoreKeyedSpecializedArrayElement(external_pointer, 1961 return new LStoreKeyedSpecializedArrayElement(external_pointer,
1969 key, 1962 key,
1970 val, 1963 val);
1971 temp);
1972 } 1964 }
1973 1965
1974 1966
1975 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { 1967 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
1976 LOperand* context = UseFixed(instr->context(), esi); 1968 LOperand* context = UseFixed(instr->context(), esi);
1977 LOperand* object = UseFixed(instr->object(), edx); 1969 LOperand* object = UseFixed(instr->object(), edx);
1978 LOperand* key = UseFixed(instr->key(), ecx); 1970 LOperand* key = UseFixed(instr->key(), ecx);
1979 LOperand* value = UseFixed(instr->value(), eax); 1971 LOperand* value = UseFixed(instr->value(), eax);
1980 1972
1981 ASSERT(instr->object()->representation().IsTagged()); 1973 ASSERT(instr->object()->representation().IsTagged());
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
2197 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { 2189 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
2198 HEnvironment* outer = current_block_->last_environment()->outer(); 2190 HEnvironment* outer = current_block_->last_environment()->outer();
2199 current_block_->UpdateEnvironment(outer); 2191 current_block_->UpdateEnvironment(outer);
2200 return NULL; 2192 return NULL;
2201 } 2193 }
2202 2194
2203 2195
2204 } } // namespace v8::internal 2196 } } // namespace v8::internal
2205 2197
2206 #endif // V8_TARGET_ARCH_IA32 2198 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« src/hydrogen.cc ('K') | « src/ia32/lithium-ia32.h ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698