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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
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 1659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1670 | 1670 |
1671 if (is_initialization_) { | 1671 if (is_initialization_) { |
1672 const Class* cls = NULL; | 1672 const Class* cls = NULL; |
1673 switch (cid) { | 1673 switch (cid) { |
1674 case kDoubleCid: | 1674 case kDoubleCid: |
1675 cls = &compiler->double_class(); | 1675 cls = &compiler->double_class(); |
1676 break; | 1676 break; |
1677 case kFloat32x4Cid: | 1677 case kFloat32x4Cid: |
1678 cls = &compiler->float32x4_class(); | 1678 cls = &compiler->float32x4_class(); |
1679 break; | 1679 break; |
| 1680 case kFloat64x2Cid: |
| 1681 cls = &compiler->float64x2_class(); |
| 1682 break; |
1680 default: | 1683 default: |
1681 UNREACHABLE(); | 1684 UNREACHABLE(); |
1682 } | 1685 } |
1683 | 1686 |
1684 StoreInstanceFieldSlowPath* slow_path = | 1687 StoreInstanceFieldSlowPath* slow_path = |
1685 new StoreInstanceFieldSlowPath(this, *cls); | 1688 new StoreInstanceFieldSlowPath(this, *cls); |
1686 compiler->AddSlowPathCode(slow_path); | 1689 compiler->AddSlowPathCode(slow_path); |
1687 | 1690 |
1688 __ TryAllocate(*cls, | 1691 __ TryAllocate(*cls, |
1689 slow_path->entry_label(), | 1692 slow_path->entry_label(), |
(...skipping 10 matching lines...) Expand all Loading... |
1700 } | 1703 } |
1701 switch (cid) { | 1704 switch (cid) { |
1702 case kDoubleCid: | 1705 case kDoubleCid: |
1703 __ Comment("UnboxedDoubleStoreInstanceFieldInstr"); | 1706 __ Comment("UnboxedDoubleStoreInstanceFieldInstr"); |
1704 __ movsd(FieldAddress(temp, Double::value_offset()), value); | 1707 __ movsd(FieldAddress(temp, Double::value_offset()), value); |
1705 break; | 1708 break; |
1706 case kFloat32x4Cid: | 1709 case kFloat32x4Cid: |
1707 __ Comment("UnboxedFloat32x4StoreInstanceFieldInstr"); | 1710 __ Comment("UnboxedFloat32x4StoreInstanceFieldInstr"); |
1708 __ movups(FieldAddress(temp, Float32x4::value_offset()), value); | 1711 __ movups(FieldAddress(temp, Float32x4::value_offset()), value); |
1709 break; | 1712 break; |
| 1713 case kFloat64x2Cid: |
| 1714 __ Comment("UnboxedFloat64x2StoreInstanceFieldInstr"); |
| 1715 __ movups(FieldAddress(temp, Float64x2::value_offset()), value); |
| 1716 break; |
1710 default: | 1717 default: |
1711 UNREACHABLE(); | 1718 UNREACHABLE(); |
1712 } | 1719 } |
1713 return; | 1720 return; |
1714 } | 1721 } |
1715 | 1722 |
1716 if (IsPotentialUnboxedStore()) { | 1723 if (IsPotentialUnboxedStore()) { |
1717 Register value_reg = locs()->in(1).reg(); | 1724 Register value_reg = locs()->in(1).reg(); |
1718 Register temp = locs()->temp(0).reg(); | 1725 Register temp = locs()->temp(0).reg(); |
1719 Register temp2 = locs()->temp(1).reg(); | 1726 Register temp2 = locs()->temp(1).reg(); |
1720 FpuRegister fpu_temp = locs()->temp(2).fpu_reg(); | 1727 FpuRegister fpu_temp = locs()->temp(2).fpu_reg(); |
1721 | 1728 |
1722 Label store_pointer; | 1729 Label store_pointer; |
1723 Label store_double; | 1730 Label store_double; |
1724 Label store_float32x4; | 1731 Label store_float32x4; |
| 1732 Label store_float64x2; |
1725 | 1733 |
1726 __ LoadObject(temp, Field::ZoneHandle(field().raw())); | 1734 __ LoadObject(temp, Field::ZoneHandle(field().raw())); |
1727 | 1735 |
1728 __ cmpl(FieldAddress(temp, Field::is_nullable_offset()), | 1736 __ cmpl(FieldAddress(temp, Field::is_nullable_offset()), |
1729 Immediate(kNullCid)); | 1737 Immediate(kNullCid)); |
1730 __ j(EQUAL, &store_pointer); | 1738 __ j(EQUAL, &store_pointer); |
1731 | 1739 |
1732 __ movzxb(temp2, FieldAddress(temp, Field::kind_bits_offset())); | 1740 __ movzxb(temp2, FieldAddress(temp, Field::kind_bits_offset())); |
1733 __ testl(temp2, Immediate(1 << Field::kUnboxingCandidateBit)); | 1741 __ testl(temp2, Immediate(1 << Field::kUnboxingCandidateBit)); |
1734 __ j(ZERO, &store_pointer); | 1742 __ j(ZERO, &store_pointer); |
1735 | 1743 |
1736 __ cmpl(FieldAddress(temp, Field::guarded_cid_offset()), | 1744 __ cmpl(FieldAddress(temp, Field::guarded_cid_offset()), |
1737 Immediate(kDoubleCid)); | 1745 Immediate(kDoubleCid)); |
1738 __ j(EQUAL, &store_double); | 1746 __ j(EQUAL, &store_double); |
1739 | 1747 |
1740 __ cmpl(FieldAddress(temp, Field::guarded_cid_offset()), | 1748 __ cmpl(FieldAddress(temp, Field::guarded_cid_offset()), |
1741 Immediate(kFloat32x4Cid)); | 1749 Immediate(kFloat32x4Cid)); |
1742 __ j(EQUAL, &store_float32x4); | 1750 __ j(EQUAL, &store_float32x4); |
1743 | 1751 |
| 1752 __ cmpl(FieldAddress(temp, Field::guarded_cid_offset()), |
| 1753 Immediate(kFloat64x2Cid)); |
| 1754 __ j(EQUAL, &store_float64x2); |
| 1755 |
1744 // Fall through. | 1756 // Fall through. |
1745 __ jmp(&store_pointer); | 1757 __ jmp(&store_pointer); |
1746 | 1758 |
1747 | 1759 |
1748 if (!compiler->is_optimizing()) { | 1760 if (!compiler->is_optimizing()) { |
1749 locs()->live_registers()->Add(locs()->in(0)); | 1761 locs()->live_registers()->Add(locs()->in(0)); |
1750 locs()->live_registers()->Add(locs()->in(1)); | 1762 locs()->live_registers()->Add(locs()->in(1)); |
1751 } | 1763 } |
1752 | 1764 |
1753 { | 1765 { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1804 __ movl(temp2, temp); | 1816 __ movl(temp2, temp); |
1805 __ StoreIntoObject(instance_reg, | 1817 __ StoreIntoObject(instance_reg, |
1806 FieldAddress(instance_reg, offset_in_bytes_), | 1818 FieldAddress(instance_reg, offset_in_bytes_), |
1807 temp2); | 1819 temp2); |
1808 | 1820 |
1809 __ Bind(©_float32x4); | 1821 __ Bind(©_float32x4); |
1810 __ movups(fpu_temp, FieldAddress(value_reg, Float32x4::value_offset())); | 1822 __ movups(fpu_temp, FieldAddress(value_reg, Float32x4::value_offset())); |
1811 __ movups(FieldAddress(temp, Float32x4::value_offset()), fpu_temp); | 1823 __ movups(FieldAddress(temp, Float32x4::value_offset()), fpu_temp); |
1812 __ jmp(&skip_store); | 1824 __ jmp(&skip_store); |
1813 } | 1825 } |
| 1826 |
| 1827 { |
| 1828 __ Bind(&store_float64x2); |
| 1829 Label copy_float64x2; |
| 1830 |
| 1831 StoreInstanceFieldSlowPath* slow_path = |
| 1832 new StoreInstanceFieldSlowPath(this, compiler->float64x2_class()); |
| 1833 compiler->AddSlowPathCode(slow_path); |
| 1834 |
| 1835 const Immediate& raw_null = |
| 1836 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1837 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes_)); |
| 1838 __ cmpl(temp, raw_null); |
| 1839 __ j(NOT_EQUAL, ©_float64x2); |
| 1840 |
| 1841 __ TryAllocate(compiler->float64x2_class(), |
| 1842 slow_path->entry_label(), |
| 1843 Assembler::kFarJump, |
| 1844 temp, |
| 1845 temp2); |
| 1846 __ Bind(slow_path->exit_label()); |
| 1847 __ movl(temp2, temp); |
| 1848 __ StoreIntoObject(instance_reg, |
| 1849 FieldAddress(instance_reg, offset_in_bytes_), |
| 1850 temp2); |
| 1851 |
| 1852 __ Bind(©_float64x2); |
| 1853 __ movups(fpu_temp, FieldAddress(value_reg, Float64x2::value_offset())); |
| 1854 __ movups(FieldAddress(temp, Float64x2::value_offset()), fpu_temp); |
| 1855 __ jmp(&skip_store); |
| 1856 } |
| 1857 |
1814 __ Bind(&store_pointer); | 1858 __ Bind(&store_pointer); |
1815 } | 1859 } |
1816 | 1860 |
1817 if (ShouldEmitStoreBarrier()) { | 1861 if (ShouldEmitStoreBarrier()) { |
1818 Register value_reg = locs()->in(1).reg(); | 1862 Register value_reg = locs()->in(1).reg(); |
1819 __ StoreIntoObject(instance_reg, | 1863 __ StoreIntoObject(instance_reg, |
1820 FieldAddress(instance_reg, offset_in_bytes_), | 1864 FieldAddress(instance_reg, offset_in_bytes_), |
1821 value_reg, | 1865 value_reg, |
1822 CanValueBeSmi()); | 1866 CanValueBeSmi()); |
1823 } else { | 1867 } else { |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2065 const intptr_t cid = field()->UnboxedFieldCid(); | 2109 const intptr_t cid = field()->UnboxedFieldCid(); |
2066 switch (cid) { | 2110 switch (cid) { |
2067 case kDoubleCid: | 2111 case kDoubleCid: |
2068 __ Comment("UnboxedDoubleLoadFieldInstr"); | 2112 __ Comment("UnboxedDoubleLoadFieldInstr"); |
2069 __ movsd(result, FieldAddress(temp, Double::value_offset())); | 2113 __ movsd(result, FieldAddress(temp, Double::value_offset())); |
2070 break; | 2114 break; |
2071 case kFloat32x4Cid: | 2115 case kFloat32x4Cid: |
2072 __ Comment("UnboxedFloat32x4LoadFieldInstr"); | 2116 __ Comment("UnboxedFloat32x4LoadFieldInstr"); |
2073 __ movups(result, FieldAddress(temp, Float32x4::value_offset())); | 2117 __ movups(result, FieldAddress(temp, Float32x4::value_offset())); |
2074 break; | 2118 break; |
| 2119 case kFloat64x2Cid: |
| 2120 __ Comment("UnboxedFloat64x2LoadFieldInstr"); |
| 2121 __ movups(result, FieldAddress(temp, Float64x2::value_offset())); |
| 2122 break; |
2075 default: | 2123 default: |
2076 UNREACHABLE(); | 2124 UNREACHABLE(); |
2077 } | 2125 } |
2078 return; | 2126 return; |
2079 } | 2127 } |
2080 | 2128 |
2081 Label done; | 2129 Label done; |
2082 Register result = locs()->out().reg(); | 2130 Register result = locs()->out().reg(); |
2083 if (IsPotentialUnboxedLoad()) { | 2131 if (IsPotentialUnboxedLoad()) { |
2084 Register temp = locs()->temp(1).reg(); | 2132 Register temp = locs()->temp(1).reg(); |
2085 XmmRegister value = locs()->temp(0).fpu_reg(); | 2133 XmmRegister value = locs()->temp(0).fpu_reg(); |
2086 | 2134 |
2087 | 2135 |
2088 Label load_pointer; | 2136 Label load_pointer; |
2089 Label load_double; | 2137 Label load_double; |
2090 Label load_float32x4; | 2138 Label load_float32x4; |
| 2139 Label load_float64x2; |
2091 | 2140 |
2092 __ LoadObject(result, Field::ZoneHandle(field()->raw())); | 2141 __ LoadObject(result, Field::ZoneHandle(field()->raw())); |
2093 | 2142 |
2094 FieldAddress field_cid_operand(result, Field::guarded_cid_offset()); | 2143 FieldAddress field_cid_operand(result, Field::guarded_cid_offset()); |
2095 FieldAddress field_nullability_operand(result, Field::is_nullable_offset()); | 2144 FieldAddress field_nullability_operand(result, Field::is_nullable_offset()); |
2096 | 2145 |
2097 __ cmpl(field_nullability_operand, Immediate(kNullCid)); | 2146 __ cmpl(field_nullability_operand, Immediate(kNullCid)); |
2098 __ j(EQUAL, &load_pointer); | 2147 __ j(EQUAL, &load_pointer); |
2099 | 2148 |
2100 __ cmpl(field_cid_operand, Immediate(kDoubleCid)); | 2149 __ cmpl(field_cid_operand, Immediate(kDoubleCid)); |
2101 __ j(EQUAL, &load_double); | 2150 __ j(EQUAL, &load_double); |
2102 | 2151 |
2103 __ cmpl(field_cid_operand, Immediate(kFloat32x4Cid)); | 2152 __ cmpl(field_cid_operand, Immediate(kFloat32x4Cid)); |
2104 __ j(EQUAL, &load_float32x4); | 2153 __ j(EQUAL, &load_float32x4); |
2105 | 2154 |
| 2155 __ cmpl(field_cid_operand, Immediate(kFloat64x2Cid)); |
| 2156 __ j(EQUAL, &load_float64x2); |
| 2157 |
2106 // Fall through. | 2158 // Fall through. |
2107 __ jmp(&load_pointer); | 2159 __ jmp(&load_pointer); |
2108 | 2160 |
2109 if (!compiler->is_optimizing()) { | 2161 if (!compiler->is_optimizing()) { |
2110 locs()->live_registers()->Add(locs()->in(0)); | 2162 locs()->live_registers()->Add(locs()->in(0)); |
2111 } | 2163 } |
2112 | 2164 |
2113 { | 2165 { |
2114 __ Bind(&load_double); | 2166 __ Bind(&load_double); |
2115 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); | 2167 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); |
(...skipping 22 matching lines...) Expand all Loading... |
2138 Assembler::kFarJump, | 2190 Assembler::kFarJump, |
2139 result, | 2191 result, |
2140 temp); | 2192 temp); |
2141 __ Bind(slow_path->exit_label()); | 2193 __ Bind(slow_path->exit_label()); |
2142 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes())); | 2194 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes())); |
2143 __ movups(value, FieldAddress(temp, Float32x4::value_offset())); | 2195 __ movups(value, FieldAddress(temp, Float32x4::value_offset())); |
2144 __ movups(FieldAddress(result, Float32x4::value_offset()), value); | 2196 __ movups(FieldAddress(result, Float32x4::value_offset()), value); |
2145 __ jmp(&done); | 2197 __ jmp(&done); |
2146 } | 2198 } |
2147 | 2199 |
| 2200 { |
| 2201 __ Bind(&load_float64x2); |
| 2202 |
| 2203 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); |
| 2204 compiler->AddSlowPathCode(slow_path); |
| 2205 |
| 2206 __ TryAllocate(compiler->float64x2_class(), |
| 2207 slow_path->entry_label(), |
| 2208 Assembler::kFarJump, |
| 2209 result, |
| 2210 temp); |
| 2211 __ Bind(slow_path->exit_label()); |
| 2212 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes())); |
| 2213 __ movups(value, FieldAddress(temp, Float64x2::value_offset())); |
| 2214 __ movups(FieldAddress(result, Float64x2::value_offset()), value); |
| 2215 __ jmp(&done); |
| 2216 } |
| 2217 |
2148 __ Bind(&load_pointer); | 2218 __ Bind(&load_pointer); |
2149 } | 2219 } |
2150 __ movl(result, FieldAddress(instance_reg, offset_in_bytes())); | 2220 __ movl(result, FieldAddress(instance_reg, offset_in_bytes())); |
2151 __ Bind(&done); | 2221 __ Bind(&done); |
2152 } | 2222 } |
2153 | 2223 |
2154 | 2224 |
2155 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const { | 2225 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const { |
2156 const intptr_t kNumInputs = 1; | 2226 const intptr_t kNumInputs = 1; |
2157 const intptr_t kNumTemps = 0; | 2227 const intptr_t kNumTemps = 0; |
(...skipping 1285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3443 } | 3513 } |
3444 | 3514 |
3445 | 3515 |
3446 void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3516 void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3447 XmmRegister value = locs()->in(0).fpu_reg(); | 3517 XmmRegister value = locs()->in(0).fpu_reg(); |
3448 | 3518 |
3449 ASSERT(locs()->out().fpu_reg() == value); | 3519 ASSERT(locs()->out().fpu_reg() == value); |
3450 | 3520 |
3451 switch (op_kind()) { | 3521 switch (op_kind()) { |
3452 case MethodRecognizer::kFloat32x4ShuffleX: | 3522 case MethodRecognizer::kFloat32x4ShuffleX: |
3453 __ shufps(value, value, Immediate(0x00)); | 3523 // Shuffle not necessary. |
3454 __ cvtss2sd(value, value); | 3524 __ cvtss2sd(value, value); |
3455 break; | 3525 break; |
3456 case MethodRecognizer::kFloat32x4ShuffleY: | 3526 case MethodRecognizer::kFloat32x4ShuffleY: |
3457 __ shufps(value, value, Immediate(0x55)); | 3527 __ shufps(value, value, Immediate(0x55)); |
3458 __ cvtss2sd(value, value); | 3528 __ cvtss2sd(value, value); |
3459 break; | 3529 break; |
3460 case MethodRecognizer::kFloat32x4ShuffleZ: | 3530 case MethodRecognizer::kFloat32x4ShuffleZ: |
3461 __ shufps(value, value, Immediate(0xAA)); | 3531 __ shufps(value, value, Immediate(0xAA)); |
3462 __ cvtss2sd(value, value); | 3532 __ cvtss2sd(value, value); |
3463 break; | 3533 break; |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3874 } | 3944 } |
3875 | 3945 |
3876 | 3946 |
3877 void Simd64x2ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3947 void Simd64x2ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3878 XmmRegister value = locs()->in(0).fpu_reg(); | 3948 XmmRegister value = locs()->in(0).fpu_reg(); |
3879 | 3949 |
3880 ASSERT(locs()->out().fpu_reg() == value); | 3950 ASSERT(locs()->out().fpu_reg() == value); |
3881 | 3951 |
3882 switch (op_kind()) { | 3952 switch (op_kind()) { |
3883 case MethodRecognizer::kFloat64x2GetX: | 3953 case MethodRecognizer::kFloat64x2GetX: |
3884 __ shufpd(value, value, Immediate(0x00)); | 3954 // nop. |
3885 break; | 3955 break; |
3886 case MethodRecognizer::kFloat64x2GetY: | 3956 case MethodRecognizer::kFloat64x2GetY: |
3887 __ shufpd(value, value, Immediate(0x33)); | 3957 __ shufpd(value, value, Immediate(0x33)); |
3888 break; | 3958 break; |
3889 default: UNREACHABLE(); | 3959 default: UNREACHABLE(); |
3890 } | 3960 } |
3891 } | 3961 } |
3892 | 3962 |
3893 | 3963 |
3894 | 3964 |
(...skipping 1838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5733 PcDescriptors::kOther, | 5803 PcDescriptors::kOther, |
5734 locs()); | 5804 locs()); |
5735 __ Drop(ArgumentCount()); // Discard arguments. | 5805 __ Drop(ArgumentCount()); // Discard arguments. |
5736 } | 5806 } |
5737 | 5807 |
5738 } // namespace dart | 5808 } // namespace dart |
5739 | 5809 |
5740 #undef __ | 5810 #undef __ |
5741 | 5811 |
5742 #endif // defined TARGET_ARCH_IA32 | 5812 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |