| OLD | NEW |
| 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 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 bool LCodeGen::IsInteger32(LConstantOperand* op) const { | 470 bool LCodeGen::IsInteger32(LConstantOperand* op) const { |
| 471 return chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32(); | 471 return chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32(); |
| 472 } | 472 } |
| 473 | 473 |
| 474 | 474 |
| 475 bool LCodeGen::IsSmi(LConstantOperand* op) const { | 475 bool LCodeGen::IsSmi(LConstantOperand* op) const { |
| 476 return chunk_->LookupLiteralRepresentation(op).IsSmi(); | 476 return chunk_->LookupLiteralRepresentation(op).IsSmi(); |
| 477 } | 477 } |
| 478 | 478 |
| 479 | 479 |
| 480 int LCodeGen::ToInteger32(LConstantOperand* op) const { | 480 int32_t LCodeGen::ToInteger32(LConstantOperand* op) const { |
| 481 HConstant* constant = chunk_->LookupConstant(op); | 481 return ToRepresentation(op, Representation::Integer32()); |
| 482 return constant->Integer32Value(); | |
| 483 } | 482 } |
| 484 | 483 |
| 485 | 484 |
| 485 int32_t LCodeGen::ToRepresentation(LConstantOperand* op, |
| 486 const Representation& r) const { |
| 487 HConstant* constant = chunk_->LookupConstant(op); |
| 488 int32_t value = constant->Integer32Value(); |
| 489 if (r.IsInteger32()) return value; |
| 490 ASSERT(r.IsSmiOrTagged()); |
| 491 return reinterpret_cast<int32_t>(Smi::FromInt(value)); |
| 492 } |
| 493 |
| 494 |
| 486 Smi* LCodeGen::ToSmi(LConstantOperand* op) const { | 495 Smi* LCodeGen::ToSmi(LConstantOperand* op) const { |
| 487 HConstant* constant = chunk_->LookupConstant(op); | 496 HConstant* constant = chunk_->LookupConstant(op); |
| 488 return Smi::FromInt(constant->Integer32Value()); | 497 return Smi::FromInt(constant->Integer32Value()); |
| 489 } | 498 } |
| 490 | 499 |
| 491 | 500 |
| 492 double LCodeGen::ToDouble(LConstantOperand* op) const { | 501 double LCodeGen::ToDouble(LConstantOperand* op) const { |
| 493 HConstant* constant = chunk_->LookupConstant(op); | 502 HConstant* constant = chunk_->LookupConstant(op); |
| 494 ASSERT(constant->HasDoubleValue()); | 503 ASSERT(constant->HasDoubleValue()); |
| 495 return constant->DoubleValue(); | 504 return constant->DoubleValue(); |
| 496 } | 505 } |
| 497 | 506 |
| 498 | 507 |
| 499 Operand LCodeGen::ToOperand(LOperand* op) { | 508 Operand LCodeGen::ToOperand(LOperand* op) { |
| 500 if (op->IsConstantOperand()) { | 509 if (op->IsConstantOperand()) { |
| 501 LConstantOperand* const_op = LConstantOperand::cast(op); | 510 LConstantOperand* const_op = LConstantOperand::cast(op); |
| 502 HConstant* constant = chunk()->LookupConstant(const_op); | 511 HConstant* constant = chunk()->LookupConstant(const_op); |
| 503 Representation r = chunk_->LookupLiteralRepresentation(const_op); | 512 Representation r = chunk_->LookupLiteralRepresentation(const_op); |
| 504 if (r.IsInteger32()) { | 513 if (r.IsSmi()) { |
| 514 ASSERT(constant->HasSmiValue()); |
| 515 return Operand(Smi::FromInt(constant->Integer32Value())); |
| 516 } else if (r.IsInteger32()) { |
| 505 ASSERT(constant->HasInteger32Value()); | 517 ASSERT(constant->HasInteger32Value()); |
| 506 return Operand(constant->Integer32Value()); | 518 return Operand(constant->Integer32Value()); |
| 507 } else if (r.IsDouble()) { | 519 } else if (r.IsDouble()) { |
| 508 Abort("ToOperand Unsupported double immediate."); | 520 Abort("ToOperand Unsupported double immediate."); |
| 509 } | 521 } |
| 510 ASSERT(r.IsTagged()); | 522 ASSERT(r.IsTagged()); |
| 511 return Operand(constant->handle()); | 523 return Operand(constant->handle()); |
| 512 } else if (op->IsRegister()) { | 524 } else if (op->IsRegister()) { |
| 513 return Operand(ToRegister(op)); | 525 return Operand(ToRegister(op)); |
| 514 } else if (op->IsDoubleRegister()) { | 526 } else if (op->IsDoubleRegister()) { |
| (...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1360 // Note that result may alias left. | 1372 // Note that result may alias left. |
| 1361 Register left = ToRegister(instr->left()); | 1373 Register left = ToRegister(instr->left()); |
| 1362 LOperand* right_op = instr->right(); | 1374 LOperand* right_op = instr->right(); |
| 1363 | 1375 |
| 1364 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 1376 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
| 1365 bool bailout_on_minus_zero = | 1377 bool bailout_on_minus_zero = |
| 1366 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); | 1378 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); |
| 1367 | 1379 |
| 1368 if (right_op->IsConstantOperand() && !can_overflow) { | 1380 if (right_op->IsConstantOperand() && !can_overflow) { |
| 1369 // Use optimized code for specific constants. | 1381 // Use optimized code for specific constants. |
| 1370 int32_t constant = ToInteger32(LConstantOperand::cast(right_op)); | 1382 int32_t constant = ToRepresentation( |
| 1383 LConstantOperand::cast(right_op), |
| 1384 instr->hydrogen()->right()->representation()); |
| 1371 | 1385 |
| 1372 if (bailout_on_minus_zero && (constant < 0)) { | 1386 if (bailout_on_minus_zero && (constant < 0)) { |
| 1373 // The case of a null constant will be handled separately. | 1387 // The case of a null constant will be handled separately. |
| 1374 // If constant is negative and left is null, the result should be -0. | 1388 // If constant is negative and left is null, the result should be -0. |
| 1375 DeoptimizeIf(eq, instr->environment(), left, Operand(zero_reg)); | 1389 DeoptimizeIf(eq, instr->environment(), left, Operand(zero_reg)); |
| 1376 } | 1390 } |
| 1377 | 1391 |
| 1378 switch (constant) { | 1392 switch (constant) { |
| 1379 case -1: | 1393 case -1: |
| 1380 __ Subu(result, zero_reg, left); | 1394 __ Subu(result, zero_reg, left); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1427 } | 1441 } |
| 1428 | 1442 |
| 1429 } else { | 1443 } else { |
| 1430 Register right = EmitLoadRegister(right_op, scratch); | 1444 Register right = EmitLoadRegister(right_op, scratch); |
| 1431 if (bailout_on_minus_zero) { | 1445 if (bailout_on_minus_zero) { |
| 1432 __ Or(ToRegister(instr->temp()), left, right); | 1446 __ Or(ToRegister(instr->temp()), left, right); |
| 1433 } | 1447 } |
| 1434 | 1448 |
| 1435 if (can_overflow) { | 1449 if (can_overflow) { |
| 1436 // hi:lo = left * right. | 1450 // hi:lo = left * right. |
| 1437 __ mult(left, right); | 1451 if (instr->hydrogen()->representation().IsSmi()) { |
| 1438 __ mfhi(scratch); | 1452 __ SmiUntag(result, left); |
| 1439 __ mflo(result); | 1453 __ mult(result, right); |
| 1454 __ mfhi(scratch); |
| 1455 __ mflo(result); |
| 1456 } else { |
| 1457 __ mult(left, right); |
| 1458 __ mfhi(scratch); |
| 1459 __ mflo(result); |
| 1460 } |
| 1440 __ sra(at, result, 31); | 1461 __ sra(at, result, 31); |
| 1441 DeoptimizeIf(ne, instr->environment(), scratch, Operand(at)); | 1462 DeoptimizeIf(ne, instr->environment(), scratch, Operand(at)); |
| 1442 } else { | 1463 } else { |
| 1443 __ Mul(result, left, right); | 1464 if (instr->hydrogen()->representation().IsSmi()) { |
| 1465 __ SmiUntag(result, left); |
| 1466 __ Mul(result, result, right); |
| 1467 } else { |
| 1468 __ Mul(result, left, right); |
| 1469 } |
| 1444 } | 1470 } |
| 1445 | 1471 |
| 1446 if (bailout_on_minus_zero) { | 1472 if (bailout_on_minus_zero) { |
| 1447 // Bail out if the result is supposed to be negative zero. | 1473 // Bail out if the result is supposed to be negative zero. |
| 1448 Label done; | 1474 Label done; |
| 1449 __ Branch(&done, ne, result, Operand(zero_reg)); | 1475 __ Branch(&done, ne, result, Operand(zero_reg)); |
| 1450 DeoptimizeIf(lt, | 1476 DeoptimizeIf(lt, |
| 1451 instr->environment(), | 1477 instr->environment(), |
| 1452 ToRegister(instr->temp()), | 1478 ToRegister(instr->temp()), |
| 1453 Operand(zero_reg)); | 1479 Operand(zero_reg)); |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1796 DeoptimizeIf(lt, instr->environment(), overflow, Operand(zero_reg)); | 1822 DeoptimizeIf(lt, instr->environment(), overflow, Operand(zero_reg)); |
| 1797 } | 1823 } |
| 1798 } | 1824 } |
| 1799 | 1825 |
| 1800 | 1826 |
| 1801 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { | 1827 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { |
| 1802 LOperand* left = instr->left(); | 1828 LOperand* left = instr->left(); |
| 1803 LOperand* right = instr->right(); | 1829 LOperand* right = instr->right(); |
| 1804 HMathMinMax::Operation operation = instr->hydrogen()->operation(); | 1830 HMathMinMax::Operation operation = instr->hydrogen()->operation(); |
| 1805 Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge; | 1831 Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge; |
| 1806 if (instr->hydrogen()->representation().IsInteger32()) { | 1832 if (instr->hydrogen()->representation().IsSmiOrInteger32()) { |
| 1807 Register left_reg = ToRegister(left); | 1833 Register left_reg = ToRegister(left); |
| 1808 Operand right_op = (right->IsRegister() || right->IsConstantOperand()) | 1834 Operand right_op = (right->IsRegister() || right->IsConstantOperand()) |
| 1809 ? ToOperand(right) | 1835 ? ToOperand(right) |
| 1810 : Operand(EmitLoadRegister(right, at)); | 1836 : Operand(EmitLoadRegister(right, at)); |
| 1811 Register result_reg = ToRegister(instr->result()); | 1837 Register result_reg = ToRegister(instr->result()); |
| 1812 Label return_right, done; | 1838 Label return_right, done; |
| 1813 if (!result_reg.is(left_reg)) { | 1839 if (!result_reg.is(left_reg)) { |
| 1814 __ Branch(&return_right, NegateCondition(condition), left_reg, right_op); | 1840 __ Branch(&return_right, NegateCondition(condition), left_reg, right_op); |
| 1815 __ mov(result_reg, left_reg); | 1841 __ mov(result_reg, left_reg); |
| 1816 __ Branch(&done); | 1842 __ Branch(&done); |
| (...skipping 3989 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5806 __ Subu(scratch, result, scratch); | 5832 __ Subu(scratch, result, scratch); |
| 5807 __ lw(result, FieldMemOperand(scratch, | 5833 __ lw(result, FieldMemOperand(scratch, |
| 5808 FixedArray::kHeaderSize - kPointerSize)); | 5834 FixedArray::kHeaderSize - kPointerSize)); |
| 5809 __ bind(&done); | 5835 __ bind(&done); |
| 5810 } | 5836 } |
| 5811 | 5837 |
| 5812 | 5838 |
| 5813 #undef __ | 5839 #undef __ |
| 5814 | 5840 |
| 5815 } } // namespace v8::internal | 5841 } } // namespace v8::internal |
| OLD | NEW |