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 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 bool LCodeGen::IsInteger32(LConstantOperand* op) const { | 491 bool LCodeGen::IsInteger32(LConstantOperand* op) const { |
492 return chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32(); | 492 return chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32(); |
493 } | 493 } |
494 | 494 |
495 | 495 |
496 bool LCodeGen::IsSmi(LConstantOperand* op) const { | 496 bool LCodeGen::IsSmi(LConstantOperand* op) const { |
497 return chunk_->LookupLiteralRepresentation(op).IsSmi(); | 497 return chunk_->LookupLiteralRepresentation(op).IsSmi(); |
498 } | 498 } |
499 | 499 |
500 | 500 |
501 int LCodeGen::ToInteger32(LConstantOperand* op) const { | 501 int32_t LCodeGen::ToInteger32(LConstantOperand* op) const { |
502 HConstant* constant = chunk_->LookupConstant(op); | 502 return ToRepresentation(op, Representation::Integer32()); |
503 return constant->Integer32Value(); | |
504 } | 503 } |
505 | 504 |
506 | 505 |
| 506 int32_t LCodeGen::ToRepresentation(LConstantOperand* op, |
| 507 const Representation& r) const { |
| 508 HConstant* constant = chunk_->LookupConstant(op); |
| 509 int32_t value = constant->Integer32Value(); |
| 510 if (r.IsInteger32()) return value; |
| 511 ASSERT(r.IsSmiOrTagged()); |
| 512 return reinterpret_cast<int32_t>(Smi::FromInt(value)); |
| 513 } |
| 514 |
| 515 |
507 Smi* LCodeGen::ToSmi(LConstantOperand* op) const { | 516 Smi* LCodeGen::ToSmi(LConstantOperand* op) const { |
508 HConstant* constant = chunk_->LookupConstant(op); | 517 HConstant* constant = chunk_->LookupConstant(op); |
509 return Smi::FromInt(constant->Integer32Value()); | 518 return Smi::FromInt(constant->Integer32Value()); |
510 } | 519 } |
511 | 520 |
512 | 521 |
513 double LCodeGen::ToDouble(LConstantOperand* op) const { | 522 double LCodeGen::ToDouble(LConstantOperand* op) const { |
514 HConstant* constant = chunk_->LookupConstant(op); | 523 HConstant* constant = chunk_->LookupConstant(op); |
515 ASSERT(constant->HasDoubleValue()); | 524 ASSERT(constant->HasDoubleValue()); |
516 return constant->DoubleValue(); | 525 return constant->DoubleValue(); |
517 } | 526 } |
518 | 527 |
519 | 528 |
520 Operand LCodeGen::ToOperand(LOperand* op) { | 529 Operand LCodeGen::ToOperand(LOperand* op) { |
521 if (op->IsConstantOperand()) { | 530 if (op->IsConstantOperand()) { |
522 LConstantOperand* const_op = LConstantOperand::cast(op); | 531 LConstantOperand* const_op = LConstantOperand::cast(op); |
523 HConstant* constant = chunk()->LookupConstant(const_op); | 532 HConstant* constant = chunk()->LookupConstant(const_op); |
524 Representation r = chunk_->LookupLiteralRepresentation(const_op); | 533 Representation r = chunk_->LookupLiteralRepresentation(const_op); |
525 if (r.IsInteger32()) { | 534 if (r.IsSmi()) { |
| 535 ASSERT(constant->HasSmiValue()); |
| 536 return Operand(Smi::FromInt(constant->Integer32Value())); |
| 537 } else if (r.IsInteger32()) { |
526 ASSERT(constant->HasInteger32Value()); | 538 ASSERT(constant->HasInteger32Value()); |
527 return Operand(constant->Integer32Value()); | 539 return Operand(constant->Integer32Value()); |
528 } else if (r.IsDouble()) { | 540 } else if (r.IsDouble()) { |
529 Abort("ToOperand Unsupported double immediate."); | 541 Abort("ToOperand Unsupported double immediate."); |
530 } | 542 } |
531 ASSERT(r.IsTagged()); | 543 ASSERT(r.IsTagged()); |
532 return Operand(constant->handle()); | 544 return Operand(constant->handle()); |
533 } else if (op->IsRegister()) { | 545 } else if (op->IsRegister()) { |
534 return Operand(ToRegister(op)); | 546 return Operand(ToRegister(op)); |
535 } else if (op->IsDoubleRegister()) { | 547 } else if (op->IsDoubleRegister()) { |
(...skipping 1001 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1537 // Note that result may alias left. | 1549 // Note that result may alias left. |
1538 Register left = ToRegister(instr->left()); | 1550 Register left = ToRegister(instr->left()); |
1539 LOperand* right_op = instr->right(); | 1551 LOperand* right_op = instr->right(); |
1540 | 1552 |
1541 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 1553 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
1542 bool bailout_on_minus_zero = | 1554 bool bailout_on_minus_zero = |
1543 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); | 1555 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); |
1544 | 1556 |
1545 if (right_op->IsConstantOperand() && !can_overflow) { | 1557 if (right_op->IsConstantOperand() && !can_overflow) { |
1546 // Use optimized code for specific constants. | 1558 // Use optimized code for specific constants. |
1547 int32_t constant = ToInteger32(LConstantOperand::cast(right_op)); | 1559 int32_t constant = ToRepresentation( |
| 1560 LConstantOperand::cast(right_op), |
| 1561 instr->hydrogen()->right()->representation()); |
1548 | 1562 |
1549 if (bailout_on_minus_zero && (constant < 0)) { | 1563 if (bailout_on_minus_zero && (constant < 0)) { |
1550 // The case of a null constant will be handled separately. | 1564 // The case of a null constant will be handled separately. |
1551 // If constant is negative and left is null, the result should be -0. | 1565 // If constant is negative and left is null, the result should be -0. |
1552 __ cmp(left, Operand::Zero()); | 1566 __ cmp(left, Operand::Zero()); |
1553 DeoptimizeIf(eq, instr->environment()); | 1567 DeoptimizeIf(eq, instr->environment()); |
1554 } | 1568 } |
1555 | 1569 |
1556 switch (constant) { | 1570 switch (constant) { |
1557 case -1: | 1571 case -1: |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1601 } | 1615 } |
1602 | 1616 |
1603 } else { | 1617 } else { |
1604 Register right = EmitLoadRegister(right_op, scratch); | 1618 Register right = EmitLoadRegister(right_op, scratch); |
1605 if (bailout_on_minus_zero) { | 1619 if (bailout_on_minus_zero) { |
1606 __ orr(ToRegister(instr->temp()), left, right); | 1620 __ orr(ToRegister(instr->temp()), left, right); |
1607 } | 1621 } |
1608 | 1622 |
1609 if (can_overflow) { | 1623 if (can_overflow) { |
1610 // scratch:result = left * right. | 1624 // scratch:result = left * right. |
1611 __ smull(result, scratch, left, right); | 1625 if (instr->hydrogen()->representation().IsSmi()) { |
| 1626 __ SmiUntag(result, left); |
| 1627 __ smull(result, scratch, result, right); |
| 1628 } else { |
| 1629 __ smull(result, scratch, left, right); |
| 1630 } |
1612 __ cmp(scratch, Operand(result, ASR, 31)); | 1631 __ cmp(scratch, Operand(result, ASR, 31)); |
1613 DeoptimizeIf(ne, instr->environment()); | 1632 DeoptimizeIf(ne, instr->environment()); |
1614 } else { | 1633 } else { |
1615 __ mul(result, left, right); | 1634 if (instr->hydrogen()->representation().IsSmi()) { |
| 1635 __ SmiUntag(result, left); |
| 1636 __ mul(result, result, right); |
| 1637 } else { |
| 1638 __ mul(result, left, right); |
| 1639 } |
1616 } | 1640 } |
1617 | 1641 |
1618 if (bailout_on_minus_zero) { | 1642 if (bailout_on_minus_zero) { |
1619 // Bail out if the result is supposed to be negative zero. | 1643 // Bail out if the result is supposed to be negative zero. |
1620 Label done; | 1644 Label done; |
1621 __ cmp(result, Operand::Zero()); | 1645 __ cmp(result, Operand::Zero()); |
1622 __ b(ne, &done); | 1646 __ b(ne, &done); |
1623 __ cmp(ToRegister(instr->temp()), Operand::Zero()); | 1647 __ cmp(ToRegister(instr->temp()), Operand::Zero()); |
1624 DeoptimizeIf(mi, instr->environment()); | 1648 DeoptimizeIf(mi, instr->environment()); |
1625 __ bind(&done); | 1649 __ bind(&done); |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1960 if (can_overflow) { | 1984 if (can_overflow) { |
1961 DeoptimizeIf(vs, instr->environment()); | 1985 DeoptimizeIf(vs, instr->environment()); |
1962 } | 1986 } |
1963 } | 1987 } |
1964 | 1988 |
1965 | 1989 |
1966 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { | 1990 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { |
1967 LOperand* left = instr->left(); | 1991 LOperand* left = instr->left(); |
1968 LOperand* right = instr->right(); | 1992 LOperand* right = instr->right(); |
1969 HMathMinMax::Operation operation = instr->hydrogen()->operation(); | 1993 HMathMinMax::Operation operation = instr->hydrogen()->operation(); |
1970 if (instr->hydrogen()->representation().IsInteger32()) { | 1994 if (instr->hydrogen()->representation().IsSmiOrInteger32()) { |
1971 Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge; | 1995 Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge; |
1972 Register left_reg = ToRegister(left); | 1996 Register left_reg = ToRegister(left); |
1973 Operand right_op = (right->IsRegister() || right->IsConstantOperand()) | 1997 Operand right_op = (right->IsRegister() || right->IsConstantOperand()) |
1974 ? ToOperand(right) | 1998 ? ToOperand(right) |
1975 : Operand(EmitLoadRegister(right, ip)); | 1999 : Operand(EmitLoadRegister(right, ip)); |
1976 Register result_reg = ToRegister(instr->result()); | 2000 Register result_reg = ToRegister(instr->result()); |
1977 __ cmp(left_reg, right_op); | 2001 __ cmp(left_reg, right_op); |
1978 __ Move(result_reg, left_reg, condition); | 2002 __ Move(result_reg, left_reg, condition); |
1979 __ mov(result_reg, right_op, LeaveCC, NegateCondition(condition)); | 2003 __ mov(result_reg, right_op, LeaveCC, NegateCondition(condition)); |
1980 } else { | 2004 } else { |
(...skipping 3843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5824 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); | 5848 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); |
5825 __ ldr(result, FieldMemOperand(scratch, | 5849 __ ldr(result, FieldMemOperand(scratch, |
5826 FixedArray::kHeaderSize - kPointerSize)); | 5850 FixedArray::kHeaderSize - kPointerSize)); |
5827 __ bind(&done); | 5851 __ bind(&done); |
5828 } | 5852 } |
5829 | 5853 |
5830 | 5854 |
5831 #undef __ | 5855 #undef __ |
5832 | 5856 |
5833 } } // namespace v8::internal | 5857 } } // namespace v8::internal |
OLD | NEW |