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 638 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
649 return ToX87Register(op->index()); | 649 return ToX87Register(op->index()); |
650 } | 650 } |
651 | 651 |
652 | 652 |
653 XMMRegister LCodeGen::ToDoubleRegister(LOperand* op) const { | 653 XMMRegister LCodeGen::ToDoubleRegister(LOperand* op) const { |
654 ASSERT(op->IsDoubleRegister()); | 654 ASSERT(op->IsDoubleRegister()); |
655 return ToDoubleRegister(op->index()); | 655 return ToDoubleRegister(op->index()); |
656 } | 656 } |
657 | 657 |
658 | 658 |
659 int LCodeGen::ToInteger32(LConstantOperand* op) const { | 659 int32_t LCodeGen::ToInteger32(LConstantOperand* op) const { |
660 HConstant* constant = chunk_->LookupConstant(op); | 660 return ToRepresentation(op, Representation::Integer32()); |
661 return constant->Integer32Value(); | |
662 } | 661 } |
663 | 662 |
664 | 663 |
| 664 int32_t LCodeGen::ToRepresentation(LConstantOperand* op, |
| 665 const Representation& r) const { |
| 666 HConstant* constant = chunk_->LookupConstant(op); |
| 667 int32_t value = constant->Integer32Value(); |
| 668 if (r.IsInteger32()) return value; |
| 669 ASSERT(r.IsSmiOrTagged()); |
| 670 return reinterpret_cast<int32_t>(Smi::FromInt(value)); |
| 671 } |
| 672 |
| 673 |
665 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { | 674 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { |
666 HConstant* constant = chunk_->LookupConstant(op); | 675 HConstant* constant = chunk_->LookupConstant(op); |
667 ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); | 676 ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); |
668 return constant->handle(); | 677 return constant->handle(); |
669 } | 678 } |
670 | 679 |
671 | 680 |
672 double LCodeGen::ToDouble(LConstantOperand* op) const { | 681 double LCodeGen::ToDouble(LConstantOperand* op) const { |
673 HConstant* constant = chunk_->LookupConstant(op); | 682 HConstant* constant = chunk_->LookupConstant(op); |
674 ASSERT(constant->HasDoubleValue()); | 683 ASSERT(constant->HasDoubleValue()); |
(...skipping 937 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1612 __ shl(left, 4); | 1621 __ shl(left, 4); |
1613 break; | 1622 break; |
1614 default: | 1623 default: |
1615 __ imul(left, left, constant); | 1624 __ imul(left, left, constant); |
1616 break; | 1625 break; |
1617 } | 1626 } |
1618 } else { | 1627 } else { |
1619 __ imul(left, left, constant); | 1628 __ imul(left, left, constant); |
1620 } | 1629 } |
1621 } else { | 1630 } else { |
| 1631 if (instr->hydrogen()->representation().IsSmi()) { |
| 1632 __ SmiUntag(left); |
| 1633 } |
1622 __ imul(left, ToOperand(right)); | 1634 __ imul(left, ToOperand(right)); |
1623 } | 1635 } |
1624 | 1636 |
1625 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 1637 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
1626 DeoptimizeIf(overflow, instr->environment()); | 1638 DeoptimizeIf(overflow, instr->environment()); |
1627 } | 1639 } |
1628 | 1640 |
1629 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1641 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
1630 // Bail out if the result is supposed to be negative zero. | 1642 // Bail out if the result is supposed to be negative zero. |
1631 Label done; | 1643 Label done; |
(...skipping 16 matching lines...) Expand all Loading... |
1648 } | 1660 } |
1649 | 1661 |
1650 | 1662 |
1651 void LCodeGen::DoBitI(LBitI* instr) { | 1663 void LCodeGen::DoBitI(LBitI* instr) { |
1652 LOperand* left = instr->left(); | 1664 LOperand* left = instr->left(); |
1653 LOperand* right = instr->right(); | 1665 LOperand* right = instr->right(); |
1654 ASSERT(left->Equals(instr->result())); | 1666 ASSERT(left->Equals(instr->result())); |
1655 ASSERT(left->IsRegister()); | 1667 ASSERT(left->IsRegister()); |
1656 | 1668 |
1657 if (right->IsConstantOperand()) { | 1669 if (right->IsConstantOperand()) { |
1658 int right_operand = ToInteger32(LConstantOperand::cast(right)); | 1670 int right_operand = ToRepresentation(LConstantOperand::cast(right), |
| 1671 instr->hydrogen()->representation()); |
1659 switch (instr->op()) { | 1672 switch (instr->op()) { |
1660 case Token::BIT_AND: | 1673 case Token::BIT_AND: |
1661 __ and_(ToRegister(left), right_operand); | 1674 __ and_(ToRegister(left), right_operand); |
1662 break; | 1675 break; |
1663 case Token::BIT_OR: | 1676 case Token::BIT_OR: |
1664 __ or_(ToRegister(left), right_operand); | 1677 __ or_(ToRegister(left), right_operand); |
1665 break; | 1678 break; |
1666 case Token::BIT_XOR: | 1679 case Token::BIT_XOR: |
1667 __ xor_(ToRegister(left), right_operand); | 1680 __ xor_(ToRegister(left), right_operand); |
1668 break; | 1681 break; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1759 } | 1772 } |
1760 } | 1773 } |
1761 | 1774 |
1762 | 1775 |
1763 void LCodeGen::DoSubI(LSubI* instr) { | 1776 void LCodeGen::DoSubI(LSubI* instr) { |
1764 LOperand* left = instr->left(); | 1777 LOperand* left = instr->left(); |
1765 LOperand* right = instr->right(); | 1778 LOperand* right = instr->right(); |
1766 ASSERT(left->Equals(instr->result())); | 1779 ASSERT(left->Equals(instr->result())); |
1767 | 1780 |
1768 if (right->IsConstantOperand()) { | 1781 if (right->IsConstantOperand()) { |
1769 __ sub(ToOperand(left), ToInteger32Immediate(right)); | 1782 __ sub(ToOperand(left), |
| 1783 ToImmediate(right, instr->hydrogen()->representation())); |
1770 } else { | 1784 } else { |
1771 __ sub(ToRegister(left), ToOperand(right)); | 1785 __ sub(ToRegister(left), ToOperand(right)); |
1772 } | 1786 } |
1773 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 1787 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
1774 DeoptimizeIf(overflow, instr->environment()); | 1788 DeoptimizeIf(overflow, instr->environment()); |
1775 } | 1789 } |
1776 } | 1790 } |
1777 | 1791 |
1778 | 1792 |
1779 void LCodeGen::DoConstantI(LConstantI* instr) { | 1793 void LCodeGen::DoConstantI(LConstantI* instr) { |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1972 } | 1986 } |
1973 } | 1987 } |
1974 | 1988 |
1975 | 1989 |
1976 void LCodeGen::DoAddI(LAddI* instr) { | 1990 void LCodeGen::DoAddI(LAddI* instr) { |
1977 LOperand* left = instr->left(); | 1991 LOperand* left = instr->left(); |
1978 LOperand* right = instr->right(); | 1992 LOperand* right = instr->right(); |
1979 | 1993 |
1980 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { | 1994 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { |
1981 if (right->IsConstantOperand()) { | 1995 if (right->IsConstantOperand()) { |
1982 int32_t offset = ToInteger32(LConstantOperand::cast(right)); | 1996 int32_t offset = ToRepresentation(LConstantOperand::cast(right), |
| 1997 instr->hydrogen()->representation()); |
1983 __ lea(ToRegister(instr->result()), MemOperand(ToRegister(left), offset)); | 1998 __ lea(ToRegister(instr->result()), MemOperand(ToRegister(left), offset)); |
1984 } else { | 1999 } else { |
1985 Operand address(ToRegister(left), ToRegister(right), times_1, 0); | 2000 Operand address(ToRegister(left), ToRegister(right), times_1, 0); |
1986 __ lea(ToRegister(instr->result()), address); | 2001 __ lea(ToRegister(instr->result()), address); |
1987 } | 2002 } |
1988 } else { | 2003 } else { |
1989 if (right->IsConstantOperand()) { | 2004 if (right->IsConstantOperand()) { |
1990 __ add(ToOperand(left), ToInteger32Immediate(right)); | 2005 __ add(ToOperand(left), |
| 2006 ToImmediate(right, instr->hydrogen()->representation())); |
1991 } else { | 2007 } else { |
1992 __ add(ToRegister(left), ToOperand(right)); | 2008 __ add(ToRegister(left), ToOperand(right)); |
1993 } | 2009 } |
1994 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 2010 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
1995 DeoptimizeIf(overflow, instr->environment()); | 2011 DeoptimizeIf(overflow, instr->environment()); |
1996 } | 2012 } |
1997 } | 2013 } |
1998 } | 2014 } |
1999 | 2015 |
2000 | 2016 |
2001 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { | 2017 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { |
2002 CpuFeatureScope scope(masm(), SSE2); | 2018 CpuFeatureScope scope(masm(), SSE2); |
2003 LOperand* left = instr->left(); | 2019 LOperand* left = instr->left(); |
2004 LOperand* right = instr->right(); | 2020 LOperand* right = instr->right(); |
2005 ASSERT(left->Equals(instr->result())); | 2021 ASSERT(left->Equals(instr->result())); |
2006 HMathMinMax::Operation operation = instr->hydrogen()->operation(); | 2022 HMathMinMax::Operation operation = instr->hydrogen()->operation(); |
2007 if (instr->hydrogen()->representation().IsInteger32()) { | 2023 if (instr->hydrogen()->representation().IsSmiOrInteger32()) { |
2008 Label return_left; | 2024 Label return_left; |
2009 Condition condition = (operation == HMathMinMax::kMathMin) | 2025 Condition condition = (operation == HMathMinMax::kMathMin) |
2010 ? less_equal | 2026 ? less_equal |
2011 : greater_equal; | 2027 : greater_equal; |
2012 if (right->IsConstantOperand()) { | 2028 if (right->IsConstantOperand()) { |
2013 Operand left_op = ToOperand(left); | 2029 Operand left_op = ToOperand(left); |
2014 Immediate right_imm = ToInteger32Immediate(right); | 2030 Immediate immediate = ToImmediate(LConstantOperand::cast(instr->right()), |
2015 __ cmp(left_op, right_imm); | 2031 instr->hydrogen()->representation()); |
| 2032 __ cmp(left_op, immediate); |
2016 __ j(condition, &return_left, Label::kNear); | 2033 __ j(condition, &return_left, Label::kNear); |
2017 __ mov(left_op, right_imm); | 2034 __ mov(left_op, immediate); |
2018 } else { | 2035 } else { |
2019 Register left_reg = ToRegister(left); | 2036 Register left_reg = ToRegister(left); |
2020 Operand right_op = ToOperand(right); | 2037 Operand right_op = ToOperand(right); |
2021 __ cmp(left_reg, right_op); | 2038 __ cmp(left_reg, right_op); |
2022 __ j(condition, &return_left, Label::kNear); | 2039 __ j(condition, &return_left, Label::kNear); |
2023 __ mov(left_reg, right_op); | 2040 __ mov(left_reg, right_op); |
2024 } | 2041 } |
2025 __ bind(&return_left); | 2042 __ bind(&return_left); |
2026 } else { | 2043 } else { |
2027 ASSERT(instr->hydrogen()->representation().IsDouble()); | 2044 ASSERT(instr->hydrogen()->representation().IsDouble()); |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2375 EmitGoto(next_block); | 2392 EmitGoto(next_block); |
2376 } else { | 2393 } else { |
2377 if (instr->is_double()) { | 2394 if (instr->is_double()) { |
2378 CpuFeatureScope scope(masm(), SSE2); | 2395 CpuFeatureScope scope(masm(), SSE2); |
2379 // Don't base result on EFLAGS when a NaN is involved. Instead | 2396 // Don't base result on EFLAGS when a NaN is involved. Instead |
2380 // jump to the false block. | 2397 // jump to the false block. |
2381 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); | 2398 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); |
2382 __ j(parity_even, instr->FalseLabel(chunk_)); | 2399 __ j(parity_even, instr->FalseLabel(chunk_)); |
2383 } else { | 2400 } else { |
2384 if (right->IsConstantOperand()) { | 2401 if (right->IsConstantOperand()) { |
2385 int32_t const_value = ToInteger32(LConstantOperand::cast(right)); | 2402 __ cmp(ToOperand(left), |
2386 if (instr->hydrogen_value()->representation().IsSmi()) { | 2403 ToImmediate(right, instr->hydrogen()->representation())); |
2387 __ cmp(ToOperand(left), Immediate(Smi::FromInt(const_value))); | |
2388 } else { | |
2389 __ cmp(ToOperand(left), Immediate(const_value)); | |
2390 } | |
2391 } else if (left->IsConstantOperand()) { | 2404 } else if (left->IsConstantOperand()) { |
2392 int32_t const_value = ToInteger32(LConstantOperand::cast(left)); | 2405 __ cmp(ToOperand(right), |
2393 if (instr->hydrogen_value()->representation().IsSmi()) { | 2406 ToImmediate(left, instr->hydrogen()->representation())); |
2394 __ cmp(ToOperand(right), Immediate(Smi::FromInt(const_value))); | |
2395 } else { | |
2396 __ cmp(ToOperand(right), Immediate(const_value)); | |
2397 } | |
2398 // We transposed the operands. Reverse the condition. | 2407 // We transposed the operands. Reverse the condition. |
2399 cc = ReverseCondition(cc); | 2408 cc = ReverseCondition(cc); |
2400 } else { | 2409 } else { |
2401 __ cmp(ToRegister(left), ToOperand(right)); | 2410 __ cmp(ToRegister(left), ToOperand(right)); |
2402 } | 2411 } |
2403 } | 2412 } |
2404 EmitBranch(instr, cc); | 2413 EmitBranch(instr, cc); |
2405 } | 2414 } |
2406 } | 2415 } |
2407 | 2416 |
(...skipping 2036 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4444 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 4453 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
4445 : isolate()->builtins()->StoreIC_Initialize(); | 4454 : isolate()->builtins()->StoreIC_Initialize(); |
4446 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 4455 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
4447 } | 4456 } |
4448 | 4457 |
4449 | 4458 |
4450 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { | 4459 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { |
4451 if (instr->hydrogen()->skip_check()) return; | 4460 if (instr->hydrogen()->skip_check()) return; |
4452 | 4461 |
4453 if (instr->index()->IsConstantOperand()) { | 4462 if (instr->index()->IsConstantOperand()) { |
4454 int constant_index = | 4463 Immediate immediate = |
4455 ToInteger32(LConstantOperand::cast(instr->index())); | 4464 ToImmediate(LConstantOperand::cast(instr->index()), |
4456 if (instr->hydrogen()->length()->representation().IsSmi()) { | 4465 instr->hydrogen()->length()->representation()); |
4457 __ cmp(ToOperand(instr->length()), | 4466 __ cmp(ToOperand(instr->length()), immediate); |
4458 Immediate(Smi::FromInt(constant_index))); | |
4459 } else { | |
4460 __ cmp(ToOperand(instr->length()), Immediate(constant_index)); | |
4461 } | |
4462 DeoptimizeIf(below_equal, instr->environment()); | 4467 DeoptimizeIf(below_equal, instr->environment()); |
4463 } else { | 4468 } else { |
4464 __ cmp(ToRegister(instr->index()), ToOperand(instr->length())); | 4469 __ cmp(ToRegister(instr->index()), ToOperand(instr->length())); |
4465 DeoptimizeIf(above_equal, instr->environment()); | 4470 DeoptimizeIf(above_equal, instr->environment()); |
4466 } | 4471 } |
4467 } | 4472 } |
4468 | 4473 |
4469 | 4474 |
4470 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { | 4475 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { |
4471 ElementsKind elements_kind = instr->elements_kind(); | 4476 ElementsKind elements_kind = instr->elements_kind(); |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4615 instr->elements(), | 4620 instr->elements(), |
4616 instr->key(), | 4621 instr->key(), |
4617 instr->hydrogen()->key()->representation(), | 4622 instr->hydrogen()->key()->representation(), |
4618 FAST_ELEMENTS, | 4623 FAST_ELEMENTS, |
4619 FixedArray::kHeaderSize - kHeapObjectTag, | 4624 FixedArray::kHeaderSize - kHeapObjectTag, |
4620 instr->additional_index()); | 4625 instr->additional_index()); |
4621 if (instr->value()->IsRegister()) { | 4626 if (instr->value()->IsRegister()) { |
4622 __ mov(operand, ToRegister(instr->value())); | 4627 __ mov(operand, ToRegister(instr->value())); |
4623 } else { | 4628 } else { |
4624 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); | 4629 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
4625 if (IsInteger32(operand_value)) { | 4630 if (IsSmi(operand_value)) { |
4626 Smi* smi_value = Smi::FromInt(ToInteger32(operand_value)); | 4631 Immediate immediate = ToImmediate(operand_value, Representation::Smi()); |
4627 __ mov(operand, Immediate(smi_value)); | 4632 __ mov(operand, immediate); |
4628 } else { | 4633 } else { |
| 4634 ASSERT(!IsInteger32(operand_value)); |
4629 Handle<Object> handle_value = ToHandle(operand_value); | 4635 Handle<Object> handle_value = ToHandle(operand_value); |
4630 __ mov(operand, handle_value); | 4636 __ mov(operand, handle_value); |
4631 } | 4637 } |
4632 } | 4638 } |
4633 | 4639 |
4634 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4640 if (instr->hydrogen()->NeedsWriteBarrier()) { |
4635 ASSERT(instr->value()->IsRegister()); | 4641 ASSERT(instr->value()->IsRegister()); |
4636 Register value = ToRegister(instr->value()); | 4642 Register value = ToRegister(instr->value()); |
4637 ASSERT(!instr->key()->IsConstantOperand()); | 4643 ASSERT(!instr->key()->IsConstantOperand()); |
4638 SmiCheck check_needed = | 4644 SmiCheck check_needed = |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4781 // result register contain a valid pointer because it is already | 4787 // result register contain a valid pointer because it is already |
4782 // contained in the register pointer map. | 4788 // contained in the register pointer map. |
4783 __ Set(result, Immediate(0)); | 4789 __ Set(result, Immediate(0)); |
4784 | 4790 |
4785 PushSafepointRegistersScope scope(this); | 4791 PushSafepointRegistersScope scope(this); |
4786 __ push(string); | 4792 __ push(string); |
4787 // Push the index as a smi. This is safe because of the checks in | 4793 // Push the index as a smi. This is safe because of the checks in |
4788 // DoStringCharCodeAt above. | 4794 // DoStringCharCodeAt above. |
4789 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue); | 4795 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue); |
4790 if (instr->index()->IsConstantOperand()) { | 4796 if (instr->index()->IsConstantOperand()) { |
4791 int const_index = ToInteger32(LConstantOperand::cast(instr->index())); | 4797 Immediate immediate = ToImmediate(LConstantOperand::cast(instr->index()), |
4792 __ push(Immediate(Smi::FromInt(const_index))); | 4798 Representation::Smi()); |
| 4799 __ push(immediate); |
4793 } else { | 4800 } else { |
4794 Register index = ToRegister(instr->index()); | 4801 Register index = ToRegister(instr->index()); |
4795 __ SmiTag(index); | 4802 __ SmiTag(index); |
4796 __ push(index); | 4803 __ push(index); |
4797 } | 4804 } |
4798 CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, | 4805 CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, |
4799 instr, instr->context()); | 4806 instr, instr->context()); |
4800 __ AssertSmi(eax); | 4807 __ AssertSmi(eax); |
4801 __ SmiUntag(eax); | 4808 __ SmiUntag(eax); |
4802 __ StoreToSafepointRegisterSlot(result, eax); | 4809 __ StoreToSafepointRegisterSlot(result, eax); |
(...skipping 1695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6498 FixedArray::kHeaderSize - kPointerSize)); | 6505 FixedArray::kHeaderSize - kPointerSize)); |
6499 __ bind(&done); | 6506 __ bind(&done); |
6500 } | 6507 } |
6501 | 6508 |
6502 | 6509 |
6503 #undef __ | 6510 #undef __ |
6504 | 6511 |
6505 } } // namespace v8::internal | 6512 } } // namespace v8::internal |
6506 | 6513 |
6507 #endif // V8_TARGET_ARCH_IA32 | 6514 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |