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 |