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 |