| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 1560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1571 | 1571 |
| 1572 if (is_initialization_) { | 1572 if (is_initialization_) { |
| 1573 const Class* cls = NULL; | 1573 const Class* cls = NULL; |
| 1574 switch (cid) { | 1574 switch (cid) { |
| 1575 case kDoubleCid: | 1575 case kDoubleCid: |
| 1576 cls = &compiler->double_class(); | 1576 cls = &compiler->double_class(); |
| 1577 break; | 1577 break; |
| 1578 case kFloat32x4Cid: | 1578 case kFloat32x4Cid: |
| 1579 cls = &compiler->float32x4_class(); | 1579 cls = &compiler->float32x4_class(); |
| 1580 break; | 1580 break; |
| 1581 case kFloat64x2Cid: |
| 1582 cls = &compiler->float64x2_class(); |
| 1583 break; |
| 1581 default: | 1584 default: |
| 1582 UNREACHABLE(); | 1585 UNREACHABLE(); |
| 1583 } | 1586 } |
| 1584 | 1587 |
| 1585 StoreInstanceFieldSlowPath* slow_path = | 1588 StoreInstanceFieldSlowPath* slow_path = |
| 1586 new StoreInstanceFieldSlowPath(this, *cls); | 1589 new StoreInstanceFieldSlowPath(this, *cls); |
| 1587 compiler->AddSlowPathCode(slow_path); | 1590 compiler->AddSlowPathCode(slow_path); |
| 1588 | 1591 |
| 1589 __ TryAllocate(*cls, | 1592 __ TryAllocate(*cls, |
| 1590 slow_path->entry_label(), | 1593 slow_path->entry_label(), |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1601 } | 1604 } |
| 1602 switch (cid) { | 1605 switch (cid) { |
| 1603 case kDoubleCid: | 1606 case kDoubleCid: |
| 1604 __ Comment("UnboxedDoubleStoreInstanceFieldInstr"); | 1607 __ Comment("UnboxedDoubleStoreInstanceFieldInstr"); |
| 1605 __ movsd(FieldAddress(temp, Double::value_offset()), value); | 1608 __ movsd(FieldAddress(temp, Double::value_offset()), value); |
| 1606 break; | 1609 break; |
| 1607 case kFloat32x4Cid: | 1610 case kFloat32x4Cid: |
| 1608 __ Comment("UnboxedFloat32x4StoreInstanceFieldInstr"); | 1611 __ Comment("UnboxedFloat32x4StoreInstanceFieldInstr"); |
| 1609 __ movups(FieldAddress(temp, Float32x4::value_offset()), value); | 1612 __ movups(FieldAddress(temp, Float32x4::value_offset()), value); |
| 1610 break; | 1613 break; |
| 1614 case kFloat64x2Cid: |
| 1615 __ Comment("UnboxedFloat64x2StoreInstanceFieldInstr"); |
| 1616 __ movups(FieldAddress(temp, Float64x2::value_offset()), value); |
| 1617 break; |
| 1611 default: | 1618 default: |
| 1612 UNREACHABLE(); | 1619 UNREACHABLE(); |
| 1613 } | 1620 } |
| 1614 return; | 1621 return; |
| 1615 } | 1622 } |
| 1616 | 1623 |
| 1617 if (IsPotentialUnboxedStore()) { | 1624 if (IsPotentialUnboxedStore()) { |
| 1618 Register value_reg = locs()->in(1).reg(); | 1625 Register value_reg = locs()->in(1).reg(); |
| 1619 Register temp = locs()->temp(0).reg(); | 1626 Register temp = locs()->temp(0).reg(); |
| 1620 Register temp2 = locs()->temp(1).reg(); | 1627 Register temp2 = locs()->temp(1).reg(); |
| 1621 FpuRegister fpu_temp = locs()->temp(2).fpu_reg(); | 1628 FpuRegister fpu_temp = locs()->temp(2).fpu_reg(); |
| 1622 | 1629 |
| 1623 Label store_pointer; | 1630 Label store_pointer; |
| 1624 Label store_double; | 1631 Label store_double; |
| 1625 Label store_float32x4; | 1632 Label store_float32x4; |
| 1633 Label store_float64x2; |
| 1626 | 1634 |
| 1627 __ LoadObject(temp, Field::ZoneHandle(field().raw()), PP); | 1635 __ LoadObject(temp, Field::ZoneHandle(field().raw()), PP); |
| 1628 | 1636 |
| 1629 __ cmpq(FieldAddress(temp, Field::is_nullable_offset()), | 1637 __ cmpq(FieldAddress(temp, Field::is_nullable_offset()), |
| 1630 Immediate(kNullCid)); | 1638 Immediate(kNullCid)); |
| 1631 __ j(EQUAL, &store_pointer); | 1639 __ j(EQUAL, &store_pointer); |
| 1632 | 1640 |
| 1633 __ movzxb(temp2, FieldAddress(temp, Field::kind_bits_offset())); | 1641 __ movzxb(temp2, FieldAddress(temp, Field::kind_bits_offset())); |
| 1634 __ testq(temp2, Immediate(1 << Field::kUnboxingCandidateBit)); | 1642 __ testq(temp2, Immediate(1 << Field::kUnboxingCandidateBit)); |
| 1635 __ j(ZERO, &store_pointer); | 1643 __ j(ZERO, &store_pointer); |
| 1636 | 1644 |
| 1637 __ cmpq(FieldAddress(temp, Field::guarded_cid_offset()), | 1645 __ cmpq(FieldAddress(temp, Field::guarded_cid_offset()), |
| 1638 Immediate(kDoubleCid)); | 1646 Immediate(kDoubleCid)); |
| 1639 __ j(EQUAL, &store_double); | 1647 __ j(EQUAL, &store_double); |
| 1640 | 1648 |
| 1641 __ cmpq(FieldAddress(temp, Field::guarded_cid_offset()), | 1649 __ cmpq(FieldAddress(temp, Field::guarded_cid_offset()), |
| 1642 Immediate(kFloat32x4Cid)); | 1650 Immediate(kFloat32x4Cid)); |
| 1643 __ j(EQUAL, &store_float32x4); | 1651 __ j(EQUAL, &store_float32x4); |
| 1644 | 1652 |
| 1653 __ cmpl(FieldAddress(temp, Field::guarded_cid_offset()), |
| 1654 Immediate(kFloat64x2Cid)); |
| 1655 __ j(EQUAL, &store_float64x2); |
| 1656 |
| 1645 // Fall through. | 1657 // Fall through. |
| 1646 __ jmp(&store_pointer); | 1658 __ jmp(&store_pointer); |
| 1647 | 1659 |
| 1648 if (!compiler->is_optimizing()) { | 1660 if (!compiler->is_optimizing()) { |
| 1649 locs()->live_registers()->Add(locs()->in(0)); | 1661 locs()->live_registers()->Add(locs()->in(0)); |
| 1650 locs()->live_registers()->Add(locs()->in(1)); | 1662 locs()->live_registers()->Add(locs()->in(1)); |
| 1651 } | 1663 } |
| 1652 | 1664 |
| 1653 { | 1665 { |
| 1654 __ Bind(&store_double); | 1666 __ Bind(&store_double); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1699 __ StoreIntoObject(instance_reg, | 1711 __ StoreIntoObject(instance_reg, |
| 1700 FieldAddress(instance_reg, offset_in_bytes_), | 1712 FieldAddress(instance_reg, offset_in_bytes_), |
| 1701 temp2); | 1713 temp2); |
| 1702 | 1714 |
| 1703 __ Bind(©_float32x4); | 1715 __ Bind(©_float32x4); |
| 1704 __ movups(fpu_temp, FieldAddress(value_reg, Float32x4::value_offset())); | 1716 __ movups(fpu_temp, FieldAddress(value_reg, Float32x4::value_offset())); |
| 1705 __ movups(FieldAddress(temp, Float32x4::value_offset()), fpu_temp); | 1717 __ movups(FieldAddress(temp, Float32x4::value_offset()), fpu_temp); |
| 1706 __ jmp(&skip_store); | 1718 __ jmp(&skip_store); |
| 1707 } | 1719 } |
| 1708 | 1720 |
| 1721 { |
| 1722 __ Bind(&store_float64x2); |
| 1723 Label copy_float64x2; |
| 1724 |
| 1725 StoreInstanceFieldSlowPath* slow_path = |
| 1726 new StoreInstanceFieldSlowPath(this, compiler->float64x2_class()); |
| 1727 compiler->AddSlowPathCode(slow_path); |
| 1728 |
| 1729 __ movq(temp, FieldAddress(instance_reg, offset_in_bytes_)); |
| 1730 __ CompareObject(temp, Object::null_object(), PP); |
| 1731 __ j(NOT_EQUAL, ©_float64x2); |
| 1732 |
| 1733 __ TryAllocate(compiler->float64x2_class(), |
| 1734 slow_path->entry_label(), |
| 1735 Assembler::kFarJump, |
| 1736 temp, |
| 1737 temp2); |
| 1738 __ Bind(slow_path->exit_label()); |
| 1739 __ movq(temp2, temp); |
| 1740 __ StoreIntoObject(instance_reg, |
| 1741 FieldAddress(instance_reg, offset_in_bytes_), |
| 1742 temp2); |
| 1743 |
| 1744 __ Bind(©_float64x2); |
| 1745 __ movups(fpu_temp, FieldAddress(value_reg, Float64x2::value_offset())); |
| 1746 __ movups(FieldAddress(temp, Float64x2::value_offset()), fpu_temp); |
| 1747 __ jmp(&skip_store); |
| 1748 } |
| 1749 |
| 1709 __ Bind(&store_pointer); | 1750 __ Bind(&store_pointer); |
| 1710 } | 1751 } |
| 1711 | 1752 |
| 1712 if (ShouldEmitStoreBarrier()) { | 1753 if (ShouldEmitStoreBarrier()) { |
| 1713 Register value_reg = locs()->in(1).reg(); | 1754 Register value_reg = locs()->in(1).reg(); |
| 1714 __ StoreIntoObject(instance_reg, | 1755 __ StoreIntoObject(instance_reg, |
| 1715 FieldAddress(instance_reg, offset_in_bytes_), | 1756 FieldAddress(instance_reg, offset_in_bytes_), |
| 1716 value_reg, | 1757 value_reg, |
| 1717 CanValueBeSmi()); | 1758 CanValueBeSmi()); |
| 1718 } else { | 1759 } else { |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1956 intptr_t cid = field()->UnboxedFieldCid(); | 1997 intptr_t cid = field()->UnboxedFieldCid(); |
| 1957 switch (cid) { | 1998 switch (cid) { |
| 1958 case kDoubleCid: | 1999 case kDoubleCid: |
| 1959 __ Comment("UnboxedDoubleLoadFieldInstr"); | 2000 __ Comment("UnboxedDoubleLoadFieldInstr"); |
| 1960 __ movsd(result, FieldAddress(temp, Double::value_offset())); | 2001 __ movsd(result, FieldAddress(temp, Double::value_offset())); |
| 1961 break; | 2002 break; |
| 1962 case kFloat32x4Cid: | 2003 case kFloat32x4Cid: |
| 1963 __ Comment("UnboxedFloat32x4LoadFieldInstr"); | 2004 __ Comment("UnboxedFloat32x4LoadFieldInstr"); |
| 1964 __ movups(result, FieldAddress(temp, Float32x4::value_offset())); | 2005 __ movups(result, FieldAddress(temp, Float32x4::value_offset())); |
| 1965 break; | 2006 break; |
| 2007 case kFloat64x2Cid: |
| 2008 __ Comment("UnboxedFloat64x2LoadFieldInstr"); |
| 2009 __ movups(result, FieldAddress(temp, Float64x2::value_offset())); |
| 2010 break; |
| 1966 default: | 2011 default: |
| 1967 UNREACHABLE(); | 2012 UNREACHABLE(); |
| 1968 } | 2013 } |
| 1969 return; | 2014 return; |
| 1970 } | 2015 } |
| 1971 | 2016 |
| 1972 Label done; | 2017 Label done; |
| 1973 Register result = locs()->out().reg(); | 2018 Register result = locs()->out().reg(); |
| 1974 if (IsPotentialUnboxedLoad()) { | 2019 if (IsPotentialUnboxedLoad()) { |
| 1975 Register temp = locs()->temp(1).reg(); | 2020 Register temp = locs()->temp(1).reg(); |
| 1976 XmmRegister value = locs()->temp(0).fpu_reg(); | 2021 XmmRegister value = locs()->temp(0).fpu_reg(); |
| 1977 | 2022 |
| 1978 Label load_pointer; | 2023 Label load_pointer; |
| 1979 Label load_double; | 2024 Label load_double; |
| 1980 Label load_float32x4; | 2025 Label load_float32x4; |
| 2026 Label load_float64x2; |
| 1981 | 2027 |
| 1982 __ LoadObject(result, Field::ZoneHandle(field()->raw()), PP); | 2028 __ LoadObject(result, Field::ZoneHandle(field()->raw()), PP); |
| 1983 | 2029 |
| 1984 __ cmpq(FieldAddress(result, Field::is_nullable_offset()), | 2030 __ cmpq(FieldAddress(result, Field::is_nullable_offset()), |
| 1985 Immediate(kNullCid)); | 2031 Immediate(kNullCid)); |
| 1986 __ j(EQUAL, &load_pointer); | 2032 __ j(EQUAL, &load_pointer); |
| 1987 | 2033 |
| 1988 __ cmpq(FieldAddress(result, Field::guarded_cid_offset()), | 2034 __ cmpq(FieldAddress(result, Field::guarded_cid_offset()), |
| 1989 Immediate(kDoubleCid)); | 2035 Immediate(kDoubleCid)); |
| 1990 __ j(EQUAL, &load_double); | 2036 __ j(EQUAL, &load_double); |
| 1991 | 2037 |
| 1992 __ cmpq(FieldAddress(result, Field::guarded_cid_offset()), | 2038 __ cmpq(FieldAddress(result, Field::guarded_cid_offset()), |
| 1993 Immediate(kFloat32x4Cid)); | 2039 Immediate(kFloat32x4Cid)); |
| 1994 __ j(EQUAL, &load_float32x4); | 2040 __ j(EQUAL, &load_float32x4); |
| 1995 | 2041 |
| 2042 __ cmpq(FieldAddress(result, Field::guarded_cid_offset()), |
| 2043 Immediate(kFloat64x2Cid)); |
| 2044 __ j(EQUAL, &load_float64x2); |
| 2045 |
| 1996 // Fall through. | 2046 // Fall through. |
| 1997 __ jmp(&load_pointer); | 2047 __ jmp(&load_pointer); |
| 1998 | 2048 |
| 1999 if (!compiler->is_optimizing()) { | 2049 if (!compiler->is_optimizing()) { |
| 2000 locs()->live_registers()->Add(locs()->in(0)); | 2050 locs()->live_registers()->Add(locs()->in(0)); |
| 2001 } | 2051 } |
| 2002 | 2052 |
| 2003 { | 2053 { |
| 2004 __ Bind(&load_double); | 2054 __ Bind(&load_double); |
| 2005 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); | 2055 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2025 slow_path->entry_label(), | 2075 slow_path->entry_label(), |
| 2026 Assembler::kFarJump, | 2076 Assembler::kFarJump, |
| 2027 result, | 2077 result, |
| 2028 PP); | 2078 PP); |
| 2029 __ Bind(slow_path->exit_label()); | 2079 __ Bind(slow_path->exit_label()); |
| 2030 __ movq(temp, FieldAddress(instance_reg, offset_in_bytes())); | 2080 __ movq(temp, FieldAddress(instance_reg, offset_in_bytes())); |
| 2031 __ movups(value, FieldAddress(temp, Float32x4::value_offset())); | 2081 __ movups(value, FieldAddress(temp, Float32x4::value_offset())); |
| 2032 __ movups(FieldAddress(result, Float32x4::value_offset()), value); | 2082 __ movups(FieldAddress(result, Float32x4::value_offset()), value); |
| 2033 __ jmp(&done); | 2083 __ jmp(&done); |
| 2034 } | 2084 } |
| 2085 { |
| 2086 __ Bind(&load_float64x2); |
| 2087 |
| 2088 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); |
| 2089 compiler->AddSlowPathCode(slow_path); |
| 2090 |
| 2091 __ TryAllocate(compiler->float64x2_class(), |
| 2092 slow_path->entry_label(), |
| 2093 Assembler::kFarJump, |
| 2094 result, |
| 2095 temp); |
| 2096 __ Bind(slow_path->exit_label()); |
| 2097 __ movq(temp, FieldAddress(instance_reg, offset_in_bytes())); |
| 2098 __ movups(value, FieldAddress(temp, Float64x2::value_offset())); |
| 2099 __ movups(FieldAddress(result, Float64x2::value_offset()), value); |
| 2100 __ jmp(&done); |
| 2101 } |
| 2035 | 2102 |
| 2036 __ Bind(&load_pointer); | 2103 __ Bind(&load_pointer); |
| 2037 } | 2104 } |
| 2038 __ movq(result, FieldAddress(instance_reg, offset_in_bytes())); | 2105 __ movq(result, FieldAddress(instance_reg, offset_in_bytes())); |
| 2039 __ Bind(&done); | 2106 __ Bind(&done); |
| 2040 } | 2107 } |
| 2041 | 2108 |
| 2042 | 2109 |
| 2043 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const { | 2110 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const { |
| 2044 const intptr_t kNumInputs = 1; | 2111 const intptr_t kNumInputs = 1; |
| (...skipping 1264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3309 } | 3376 } |
| 3310 | 3377 |
| 3311 | 3378 |
| 3312 void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3379 void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3313 XmmRegister value = locs()->in(0).fpu_reg(); | 3380 XmmRegister value = locs()->in(0).fpu_reg(); |
| 3314 | 3381 |
| 3315 ASSERT(locs()->out().fpu_reg() == value); | 3382 ASSERT(locs()->out().fpu_reg() == value); |
| 3316 | 3383 |
| 3317 switch (op_kind()) { | 3384 switch (op_kind()) { |
| 3318 case MethodRecognizer::kFloat32x4ShuffleX: | 3385 case MethodRecognizer::kFloat32x4ShuffleX: |
| 3319 __ shufps(value, value, Immediate(0x00)); | 3386 // Shuffle not necessary. |
| 3320 __ cvtss2sd(value, value); | 3387 __ cvtss2sd(value, value); |
| 3321 break; | 3388 break; |
| 3322 case MethodRecognizer::kFloat32x4ShuffleY: | 3389 case MethodRecognizer::kFloat32x4ShuffleY: |
| 3323 __ shufps(value, value, Immediate(0x55)); | 3390 __ shufps(value, value, Immediate(0x55)); |
| 3324 __ cvtss2sd(value, value); | 3391 __ cvtss2sd(value, value); |
| 3325 break; | 3392 break; |
| 3326 case MethodRecognizer::kFloat32x4ShuffleZ: | 3393 case MethodRecognizer::kFloat32x4ShuffleZ: |
| 3327 __ shufps(value, value, Immediate(0xAA)); | 3394 __ shufps(value, value, Immediate(0xAA)); |
| 3328 __ cvtss2sd(value, value); | 3395 __ cvtss2sd(value, value); |
| 3329 break; | 3396 break; |
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3739 return summary; | 3806 return summary; |
| 3740 } | 3807 } |
| 3741 | 3808 |
| 3742 | 3809 |
| 3743 void Simd64x2ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3810 void Simd64x2ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3744 XmmRegister value = locs()->in(0).fpu_reg(); | 3811 XmmRegister value = locs()->in(0).fpu_reg(); |
| 3745 | 3812 |
| 3746 ASSERT(locs()->out().fpu_reg() == value); | 3813 ASSERT(locs()->out().fpu_reg() == value); |
| 3747 switch (op_kind()) { | 3814 switch (op_kind()) { |
| 3748 case MethodRecognizer::kFloat64x2GetX: | 3815 case MethodRecognizer::kFloat64x2GetX: |
| 3749 __ shufpd(value, value, Immediate(0x00)); | 3816 // nop. |
| 3750 break; | 3817 break; |
| 3751 case MethodRecognizer::kFloat64x2GetY: | 3818 case MethodRecognizer::kFloat64x2GetY: |
| 3752 __ shufpd(value, value, Immediate(0x33)); | 3819 __ shufpd(value, value, Immediate(0x33)); |
| 3753 break; | 3820 break; |
| 3754 default: UNREACHABLE(); | 3821 default: UNREACHABLE(); |
| 3755 } | 3822 } |
| 3756 } | 3823 } |
| 3757 | 3824 |
| 3758 | 3825 |
| 3759 LocationSummary* Float64x2ZeroInstr::MakeLocationSummary(bool opt) const { | 3826 LocationSummary* Float64x2ZeroInstr::MakeLocationSummary(bool opt) const { |
| (...skipping 1573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5333 PcDescriptors::kOther, | 5400 PcDescriptors::kOther, |
| 5334 locs()); | 5401 locs()); |
| 5335 __ Drop(ArgumentCount()); // Discard arguments. | 5402 __ Drop(ArgumentCount()); // Discard arguments. |
| 5336 } | 5403 } |
| 5337 | 5404 |
| 5338 } // namespace dart | 5405 } // namespace dart |
| 5339 | 5406 |
| 5340 #undef __ | 5407 #undef __ |
| 5341 | 5408 |
| 5342 #endif // defined TARGET_ARCH_X64 | 5409 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |