| 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 |