| 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_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 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 811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 822 case kImmutableArrayCid: | 822 case kImmutableArrayCid: |
| 823 return CompileType::Dynamic(); | 823 return CompileType::Dynamic(); |
| 824 | 824 |
| 825 case kTypedDataFloat32ArrayCid: | 825 case kTypedDataFloat32ArrayCid: |
| 826 case kTypedDataFloat64ArrayCid: | 826 case kTypedDataFloat64ArrayCid: |
| 827 return CompileType::FromCid(kDoubleCid); | 827 return CompileType::FromCid(kDoubleCid); |
| 828 case kTypedDataFloat32x4ArrayCid: | 828 case kTypedDataFloat32x4ArrayCid: |
| 829 return CompileType::FromCid(kFloat32x4Cid); | 829 return CompileType::FromCid(kFloat32x4Cid); |
| 830 case kTypedDataInt32x4ArrayCid: | 830 case kTypedDataInt32x4ArrayCid: |
| 831 return CompileType::FromCid(kInt32x4Cid); | 831 return CompileType::FromCid(kInt32x4Cid); |
| 832 case kTypedDataFloat64x2ArrayCid: |
| 833 return CompileType::FromCid(kFloat64x2Cid); |
| 832 | 834 |
| 833 case kTypedDataInt8ArrayCid: | 835 case kTypedDataInt8ArrayCid: |
| 834 case kTypedDataUint8ArrayCid: | 836 case kTypedDataUint8ArrayCid: |
| 835 case kTypedDataUint8ClampedArrayCid: | 837 case kTypedDataUint8ClampedArrayCid: |
| 836 case kExternalTypedDataUint8ArrayCid: | 838 case kExternalTypedDataUint8ArrayCid: |
| 837 case kExternalTypedDataUint8ClampedArrayCid: | 839 case kExternalTypedDataUint8ClampedArrayCid: |
| 838 case kTypedDataInt16ArrayCid: | 840 case kTypedDataInt16ArrayCid: |
| 839 case kTypedDataUint16ArrayCid: | 841 case kTypedDataUint16ArrayCid: |
| 840 case kOneByteStringCid: | 842 case kOneByteStringCid: |
| 841 case kTwoByteStringCid: | 843 case kTwoByteStringCid: |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 875 // Instruction can deoptimize if we optimistically assumed that the result | 877 // Instruction can deoptimize if we optimistically assumed that the result |
| 876 // fits into Smi. | 878 // fits into Smi. |
| 877 return CanDeoptimize() ? kTagged : kUnboxedMint; | 879 return CanDeoptimize() ? kTagged : kUnboxedMint; |
| 878 case kTypedDataFloat32ArrayCid: | 880 case kTypedDataFloat32ArrayCid: |
| 879 case kTypedDataFloat64ArrayCid: | 881 case kTypedDataFloat64ArrayCid: |
| 880 return kUnboxedDouble; | 882 return kUnboxedDouble; |
| 881 case kTypedDataInt32x4ArrayCid: | 883 case kTypedDataInt32x4ArrayCid: |
| 882 return kUnboxedInt32x4; | 884 return kUnboxedInt32x4; |
| 883 case kTypedDataFloat32x4ArrayCid: | 885 case kTypedDataFloat32x4ArrayCid: |
| 884 return kUnboxedFloat32x4; | 886 return kUnboxedFloat32x4; |
| 887 case kTypedDataFloat64x2ArrayCid: |
| 888 return kUnboxedFloat64x2; |
| 885 default: | 889 default: |
| 886 UNREACHABLE(); | 890 UNREACHABLE(); |
| 887 return kTagged; | 891 return kTagged; |
| 888 } | 892 } |
| 889 } | 893 } |
| 890 | 894 |
| 891 | 895 |
| 892 LocationSummary* LoadIndexedInstr::MakeLocationSummary(bool opt) const { | 896 LocationSummary* LoadIndexedInstr::MakeLocationSummary(bool opt) const { |
| 893 const intptr_t kNumInputs = 2; | 897 const intptr_t kNumInputs = 2; |
| 894 const intptr_t kNumTemps = 0; | 898 const intptr_t kNumTemps = 0; |
| 895 LocationSummary* locs = | 899 LocationSummary* locs = |
| 896 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 900 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 897 locs->set_in(0, Location::RequiresRegister()); | 901 locs->set_in(0, Location::RequiresRegister()); |
| 898 // The smi index is either untagged (element size == 1), or it is left smi | 902 // The smi index is either untagged (element size == 1), or it is left smi |
| 899 // tagged (for all element sizes > 1). | 903 // tagged (for all element sizes > 1). |
| 900 // TODO(regis): Revisit and see if the index can be immediate. | 904 // TODO(regis): Revisit and see if the index can be immediate. |
| 901 locs->set_in(1, Location::WritableRegister()); | 905 locs->set_in(1, Location::WritableRegister()); |
| 902 if ((representation() == kUnboxedDouble) || | 906 if ((representation() == kUnboxedDouble) || |
| 903 (representation() == kUnboxedFloat32x4) || | 907 (representation() == kUnboxedFloat32x4) || |
| 904 (representation() == kUnboxedInt32x4)) { | 908 (representation() == kUnboxedInt32x4) || |
| 909 (representation() == kUnboxedFloat64x2)) { |
| 905 locs->set_out(Location::RequiresFpuRegister()); | 910 locs->set_out(Location::RequiresFpuRegister()); |
| 906 } else { | 911 } else { |
| 907 locs->set_out(Location::RequiresRegister()); | 912 locs->set_out(Location::RequiresRegister()); |
| 908 } | 913 } |
| 909 return locs; | 914 return locs; |
| 910 } | 915 } |
| 911 | 916 |
| 912 | 917 |
| 913 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 918 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 914 Register array = locs()->in(0).reg(); | 919 Register array = locs()->in(0).reg(); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 944 UNREACHABLE(); | 949 UNREACHABLE(); |
| 945 } | 950 } |
| 946 | 951 |
| 947 if (!IsExternal()) { | 952 if (!IsExternal()) { |
| 948 ASSERT(this->array()->definition()->representation() == kTagged); | 953 ASSERT(this->array()->definition()->representation() == kTagged); |
| 949 __ AddImmediate(index.reg(), | 954 __ AddImmediate(index.reg(), |
| 950 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); | 955 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); |
| 951 } | 956 } |
| 952 element_address = Address(array, index.reg(), LSL, 0); | 957 element_address = Address(array, index.reg(), LSL, 0); |
| 953 | 958 |
| 954 if ((representation() == kUnboxedDouble) || | 959 if ((representation() == kUnboxedDouble) || |
| 955 (representation() == kUnboxedMint) || | 960 (representation() == kUnboxedMint) || |
| 956 (representation() == kUnboxedFloat32x4) || | 961 (representation() == kUnboxedFloat32x4) || |
| 957 (representation() == kUnboxedInt32x4)) { | 962 (representation() == kUnboxedInt32x4) || |
| 963 (representation() == kUnboxedFloat64x2)) { |
| 958 QRegister result = locs()->out().fpu_reg(); | 964 QRegister result = locs()->out().fpu_reg(); |
| 959 DRegister dresult0 = EvenDRegisterOf(result); | 965 DRegister dresult0 = EvenDRegisterOf(result); |
| 960 DRegister dresult1 = OddDRegisterOf(result); | 966 DRegister dresult1 = OddDRegisterOf(result); |
| 961 switch (class_id()) { | 967 switch (class_id()) { |
| 962 case kTypedDataInt32ArrayCid: | 968 case kTypedDataInt32ArrayCid: |
| 963 UNIMPLEMENTED(); | 969 UNIMPLEMENTED(); |
| 964 break; | 970 break; |
| 965 case kTypedDataUint32ArrayCid: | 971 case kTypedDataUint32ArrayCid: |
| 966 UNIMPLEMENTED(); | 972 UNIMPLEMENTED(); |
| 967 break; | 973 break; |
| 968 case kTypedDataFloat32ArrayCid: | 974 case kTypedDataFloat32ArrayCid: |
| 969 // Load single precision float and promote to double. | 975 // Load single precision float and promote to double. |
| 970 // vldrs does not support indexed addressing. | 976 // vldrs does not support indexed addressing. |
| 971 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 977 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 972 element_address = Address(index.reg(), 0); | 978 element_address = Address(index.reg(), 0); |
| 973 __ vldrs(STMP, element_address); | 979 __ vldrs(STMP, element_address); |
| 974 __ vcvtds(dresult0, STMP); | 980 __ vcvtds(dresult0, STMP); |
| 975 break; | 981 break; |
| 976 case kTypedDataFloat64ArrayCid: | 982 case kTypedDataFloat64ArrayCid: |
| 977 // vldrd does not support indexed addressing. | 983 // vldrd does not support indexed addressing. |
| 978 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 984 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 979 element_address = Address(index.reg(), 0); | 985 element_address = Address(index.reg(), 0); |
| 980 __ vldrd(dresult0, element_address); | 986 __ vldrd(dresult0, element_address); |
| 981 break; | 987 break; |
| 988 case kTypedDataFloat64x2ArrayCid: |
| 982 case kTypedDataInt32x4ArrayCid: | 989 case kTypedDataInt32x4ArrayCid: |
| 983 case kTypedDataFloat32x4ArrayCid: | 990 case kTypedDataFloat32x4ArrayCid: |
| 984 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 991 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 992 // TODO(zra): Maybe use vldmd here. |
| 985 __ LoadDFromOffset(dresult0, index.reg(), 0); | 993 __ LoadDFromOffset(dresult0, index.reg(), 0); |
| 986 __ LoadDFromOffset(dresult1, index.reg(), 2*kWordSize); | 994 __ LoadDFromOffset(dresult1, index.reg(), 2 * kWordSize); |
| 987 break; | 995 break; |
| 988 } | 996 } |
| 989 return; | 997 return; |
| 990 } | 998 } |
| 991 | 999 |
| 992 Register result = locs()->out().reg(); | 1000 Register result = locs()->out().reg(); |
| 993 switch (class_id()) { | 1001 switch (class_id()) { |
| 994 case kTypedDataInt8ArrayCid: | 1002 case kTypedDataInt8ArrayCid: |
| 995 ASSERT(index_scale() == 1); | 1003 ASSERT(index_scale() == 1); |
| 996 __ ldrsb(result, element_address); | 1004 __ ldrsb(result, element_address); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1060 case kTypedDataInt32ArrayCid: | 1068 case kTypedDataInt32ArrayCid: |
| 1061 case kTypedDataUint32ArrayCid: | 1069 case kTypedDataUint32ArrayCid: |
| 1062 return value()->IsSmiValue() ? kTagged : kUnboxedMint; | 1070 return value()->IsSmiValue() ? kTagged : kUnboxedMint; |
| 1063 case kTypedDataFloat32ArrayCid: | 1071 case kTypedDataFloat32ArrayCid: |
| 1064 case kTypedDataFloat64ArrayCid: | 1072 case kTypedDataFloat64ArrayCid: |
| 1065 return kUnboxedDouble; | 1073 return kUnboxedDouble; |
| 1066 case kTypedDataFloat32x4ArrayCid: | 1074 case kTypedDataFloat32x4ArrayCid: |
| 1067 return kUnboxedFloat32x4; | 1075 return kUnboxedFloat32x4; |
| 1068 case kTypedDataInt32x4ArrayCid: | 1076 case kTypedDataInt32x4ArrayCid: |
| 1069 return kUnboxedInt32x4; | 1077 return kUnboxedInt32x4; |
| 1078 case kTypedDataFloat64x2ArrayCid: |
| 1079 return kUnboxedFloat64x2; |
| 1070 default: | 1080 default: |
| 1071 UNREACHABLE(); | 1081 UNREACHABLE(); |
| 1072 return kTagged; | 1082 return kTagged; |
| 1073 } | 1083 } |
| 1074 } | 1084 } |
| 1075 | 1085 |
| 1076 | 1086 |
| 1077 LocationSummary* StoreIndexedInstr::MakeLocationSummary(bool opt) const { | 1087 LocationSummary* StoreIndexedInstr::MakeLocationSummary(bool opt) const { |
| 1078 const intptr_t kNumInputs = 3; | 1088 const intptr_t kNumInputs = 3; |
| 1079 const intptr_t kNumTemps = 0; | 1089 const intptr_t kNumTemps = 0; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1099 case kTypedDataInt16ArrayCid: | 1109 case kTypedDataInt16ArrayCid: |
| 1100 case kTypedDataUint16ArrayCid: | 1110 case kTypedDataUint16ArrayCid: |
| 1101 case kTypedDataInt32ArrayCid: | 1111 case kTypedDataInt32ArrayCid: |
| 1102 case kTypedDataUint32ArrayCid: | 1112 case kTypedDataUint32ArrayCid: |
| 1103 locs->set_in(2, Location::WritableRegister()); | 1113 locs->set_in(2, Location::WritableRegister()); |
| 1104 break; | 1114 break; |
| 1105 case kTypedDataFloat32ArrayCid: | 1115 case kTypedDataFloat32ArrayCid: |
| 1106 case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants. | 1116 case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants. |
| 1107 case kTypedDataInt32x4ArrayCid: | 1117 case kTypedDataInt32x4ArrayCid: |
| 1108 case kTypedDataFloat32x4ArrayCid: | 1118 case kTypedDataFloat32x4ArrayCid: |
| 1119 case kTypedDataFloat64x2ArrayCid: |
| 1109 locs->set_in(2, Location::RequiresFpuRegister()); | 1120 locs->set_in(2, Location::RequiresFpuRegister()); |
| 1110 break; | 1121 break; |
| 1111 default: | 1122 default: |
| 1112 UNREACHABLE(); | 1123 UNREACHABLE(); |
| 1113 return NULL; | 1124 return NULL; |
| 1114 } | 1125 } |
| 1115 return locs; | 1126 return locs; |
| 1116 } | 1127 } |
| 1117 | 1128 |
| 1118 | 1129 |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1238 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1249 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 1239 __ StoreSToOffset(STMP, index.reg(), 0); | 1250 __ StoreSToOffset(STMP, index.reg(), 0); |
| 1240 break; | 1251 break; |
| 1241 } | 1252 } |
| 1242 case kTypedDataFloat64ArrayCid: { | 1253 case kTypedDataFloat64ArrayCid: { |
| 1243 DRegister in2 = EvenDRegisterOf(locs()->in(2).fpu_reg()); | 1254 DRegister in2 = EvenDRegisterOf(locs()->in(2).fpu_reg()); |
| 1244 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1255 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 1245 __ StoreDToOffset(in2, index.reg(), 0); | 1256 __ StoreDToOffset(in2, index.reg(), 0); |
| 1246 break; | 1257 break; |
| 1247 } | 1258 } |
| 1259 case kTypedDataFloat64x2ArrayCid: |
| 1248 case kTypedDataInt32x4ArrayCid: | 1260 case kTypedDataInt32x4ArrayCid: |
| 1249 case kTypedDataFloat32x4ArrayCid: { | 1261 case kTypedDataFloat32x4ArrayCid: { |
| 1250 QRegister in = locs()->in(2).fpu_reg(); | 1262 QRegister in = locs()->in(2).fpu_reg(); |
| 1251 DRegister din0 = EvenDRegisterOf(in); | 1263 DRegister din0 = EvenDRegisterOf(in); |
| 1252 DRegister din1 = OddDRegisterOf(in); | 1264 DRegister din1 = OddDRegisterOf(in); |
| 1253 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1265 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 1254 __ StoreDToOffset(din0, index.reg(), 0); | 1266 __ StoreDToOffset(din0, index.reg(), 0); |
| 1255 __ StoreDToOffset(din1, index.reg(), 2*kWordSize); | 1267 __ StoreDToOffset(din1, index.reg(), 2 * kWordSize); |
| 1256 break; | 1268 break; |
| 1257 } | 1269 } |
| 1258 default: | 1270 default: |
| 1259 UNREACHABLE(); | 1271 UNREACHABLE(); |
| 1260 } | 1272 } |
| 1261 } | 1273 } |
| 1262 | 1274 |
| 1263 | 1275 |
| 1264 LocationSummary* GuardFieldInstr::MakeLocationSummary(bool opt) const { | 1276 LocationSummary* GuardFieldInstr::MakeLocationSummary(bool opt) const { |
| 1265 const intptr_t kNumInputs = 1; | 1277 const intptr_t kNumInputs = 1; |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1690 switch (cid) { | 1702 switch (cid) { |
| 1691 case kDoubleCid: | 1703 case kDoubleCid: |
| 1692 __ Comment("UnboxedDoubleStoreInstanceFieldInstr"); | 1704 __ Comment("UnboxedDoubleStoreInstanceFieldInstr"); |
| 1693 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag); | 1705 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag); |
| 1694 break; | 1706 break; |
| 1695 case kFloat32x4Cid: | 1707 case kFloat32x4Cid: |
| 1696 __ Comment("UnboxedFloat32x4StoreInstanceFieldInstr"); | 1708 __ Comment("UnboxedFloat32x4StoreInstanceFieldInstr"); |
| 1697 __ StoreDToOffset(value, temp, | 1709 __ StoreDToOffset(value, temp, |
| 1698 Float32x4::value_offset() - kHeapObjectTag); | 1710 Float32x4::value_offset() - kHeapObjectTag); |
| 1699 __ StoreDToOffset(value_odd, temp, | 1711 __ StoreDToOffset(value_odd, temp, |
| 1700 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 1712 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 1701 break; | 1713 break; |
| 1702 default: | 1714 default: |
| 1703 UNREACHABLE(); | 1715 UNREACHABLE(); |
| 1704 } | 1716 } |
| 1705 | 1717 |
| 1706 return; | 1718 return; |
| 1707 } | 1719 } |
| 1708 | 1720 |
| 1709 if (IsPotentialUnboxedStore()) { | 1721 if (IsPotentialUnboxedStore()) { |
| 1710 Register value_reg = locs()->in(1).reg(); | 1722 Register value_reg = locs()->in(1).reg(); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1789 __ TryAllocate(compiler->float32x4_class(), | 1801 __ TryAllocate(compiler->float32x4_class(), |
| 1790 slow_path->entry_label(), | 1802 slow_path->entry_label(), |
| 1791 temp, | 1803 temp, |
| 1792 temp2); | 1804 temp2); |
| 1793 __ Bind(slow_path->exit_label()); | 1805 __ Bind(slow_path->exit_label()); |
| 1794 __ MoveRegister(temp2, temp); | 1806 __ MoveRegister(temp2, temp); |
| 1795 __ StoreIntoObject(instance_reg, | 1807 __ StoreIntoObject(instance_reg, |
| 1796 FieldAddress(instance_reg, field().Offset()), | 1808 FieldAddress(instance_reg, field().Offset()), |
| 1797 temp2); | 1809 temp2); |
| 1798 __ Bind(©_float32x4); | 1810 __ Bind(©_float32x4); |
| 1811 // TODO(zra): Maybe use vldmd here. |
| 1799 __ LoadDFromOffset(fpu_temp, value_reg, | 1812 __ LoadDFromOffset(fpu_temp, value_reg, |
| 1800 Float32x4::value_offset() - kHeapObjectTag); | 1813 Float32x4::value_offset() - kHeapObjectTag); |
| 1801 __ LoadDFromOffset(fpu_temp_odd, value_reg, | 1814 __ LoadDFromOffset(fpu_temp_odd, value_reg, |
| 1802 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 1815 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 1803 __ StoreDToOffset(fpu_temp, temp, | 1816 __ StoreDToOffset(fpu_temp, temp, |
| 1804 Float32x4::value_offset() - kHeapObjectTag); | 1817 Float32x4::value_offset() - kHeapObjectTag); |
| 1805 __ StoreDToOffset(fpu_temp_odd, temp, | 1818 __ StoreDToOffset(fpu_temp_odd, temp, |
| 1806 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 1819 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 1807 __ b(&skip_store); | 1820 __ b(&skip_store); |
| 1808 } | 1821 } |
| 1809 | 1822 |
| 1810 __ Bind(&store_pointer); | 1823 __ Bind(&store_pointer); |
| 1811 } | 1824 } |
| 1812 | 1825 |
| 1813 if (ShouldEmitStoreBarrier()) { | 1826 if (ShouldEmitStoreBarrier()) { |
| 1814 Register value_reg = locs()->in(1).reg(); | 1827 Register value_reg = locs()->in(1).reg(); |
| 1815 __ StoreIntoObject(instance_reg, | 1828 __ StoreIntoObject(instance_reg, |
| 1816 FieldAddress(instance_reg, field().Offset()), | 1829 FieldAddress(instance_reg, field().Offset()), |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1988 compiler->RestoreLiveRegisters(locs); | 2001 compiler->RestoreLiveRegisters(locs); |
| 1989 | 2002 |
| 1990 __ b(exit_label()); | 2003 __ b(exit_label()); |
| 1991 } | 2004 } |
| 1992 | 2005 |
| 1993 private: | 2006 private: |
| 1994 Instruction* instruction_; | 2007 Instruction* instruction_; |
| 1995 }; | 2008 }; |
| 1996 | 2009 |
| 1997 | 2010 |
| 2011 class BoxFloat64x2SlowPath : public SlowPathCode { |
| 2012 public: |
| 2013 explicit BoxFloat64x2SlowPath(Instruction* instruction) |
| 2014 : instruction_(instruction) { } |
| 2015 |
| 2016 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2017 __ Comment("BoxFloat64x2SlowPath"); |
| 2018 __ Bind(entry_label()); |
| 2019 const Class& float64x2_class = compiler->float64x2_class(); |
| 2020 const Code& stub = |
| 2021 Code::Handle(StubCode::GetAllocationStubForClass(float64x2_class)); |
| 2022 const ExternalLabel label(float64x2_class.ToCString(), stub.EntryPoint()); |
| 2023 |
| 2024 LocationSummary* locs = instruction_->locs(); |
| 2025 locs->live_registers()->Remove(locs->out()); |
| 2026 |
| 2027 compiler->SaveLiveRegisters(locs); |
| 2028 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. |
| 2029 &label, |
| 2030 PcDescriptors::kOther, |
| 2031 locs); |
| 2032 __ mov(locs->out().reg(), ShifterOperand(R0)); |
| 2033 compiler->RestoreLiveRegisters(locs); |
| 2034 |
| 2035 __ b(exit_label()); |
| 2036 } |
| 2037 |
| 2038 private: |
| 2039 Instruction* instruction_; |
| 2040 }; |
| 2041 |
| 2042 |
| 1998 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const { | 2043 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const { |
| 1999 const intptr_t kNumInputs = 1; | 2044 const intptr_t kNumInputs = 1; |
| 2000 const intptr_t kNumTemps = 0; | 2045 const intptr_t kNumTemps = 0; |
| 2001 LocationSummary* locs = | 2046 LocationSummary* locs = |
| 2002 new LocationSummary( | 2047 new LocationSummary( |
| 2003 kNumInputs, kNumTemps, | 2048 kNumInputs, kNumTemps, |
| 2004 (opt && !IsPotentialUnboxedLoad()) | 2049 (opt && !IsPotentialUnboxedLoad()) |
| 2005 ? LocationSummary::kNoCall | 2050 ? LocationSummary::kNoCall |
| 2006 : LocationSummary::kCallOnSlowPath); | 2051 : LocationSummary::kCallOnSlowPath); |
| 2007 | 2052 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2028 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); | 2073 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); |
| 2029 intptr_t cid = field()->UnboxedFieldCid(); | 2074 intptr_t cid = field()->UnboxedFieldCid(); |
| 2030 switch (cid) { | 2075 switch (cid) { |
| 2031 case kDoubleCid: | 2076 case kDoubleCid: |
| 2032 __ Comment("UnboxedDoubleLoadFieldInstr"); | 2077 __ Comment("UnboxedDoubleLoadFieldInstr"); |
| 2033 __ LoadDFromOffset(result, temp, | 2078 __ LoadDFromOffset(result, temp, |
| 2034 Double::value_offset() - kHeapObjectTag); | 2079 Double::value_offset() - kHeapObjectTag); |
| 2035 break; | 2080 break; |
| 2036 case kFloat32x4Cid: | 2081 case kFloat32x4Cid: |
| 2037 __ Comment("UnboxedFloat32x4LoadFieldInstr"); | 2082 __ Comment("UnboxedFloat32x4LoadFieldInstr"); |
| 2083 // TODO(zra): Maybe use vldmd here. |
| 2038 __ LoadDFromOffset(result, temp, | 2084 __ LoadDFromOffset(result, temp, |
| 2039 Float32x4::value_offset() - kHeapObjectTag); | 2085 Float32x4::value_offset() - kHeapObjectTag); |
| 2040 __ LoadDFromOffset(result_odd, temp, | 2086 __ LoadDFromOffset(result_odd, temp, |
| 2041 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 2087 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 2042 break; | 2088 break; |
| 2043 default: | 2089 default: |
| 2044 UNREACHABLE(); | 2090 UNREACHABLE(); |
| 2045 } | 2091 } |
| 2046 return; | 2092 return; |
| 2047 } | 2093 } |
| 2048 | 2094 |
| 2049 Label done; | 2095 Label done; |
| 2050 Register result_reg = locs()->out().reg(); | 2096 Register result_reg = locs()->out().reg(); |
| 2051 if (IsPotentialUnboxedLoad()) { | 2097 if (IsPotentialUnboxedLoad()) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2104 __ Bind(&load_float32x4); | 2150 __ Bind(&load_float32x4); |
| 2105 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); | 2151 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); |
| 2106 compiler->AddSlowPathCode(slow_path); | 2152 compiler->AddSlowPathCode(slow_path); |
| 2107 | 2153 |
| 2108 __ TryAllocate(compiler->float32x4_class(), | 2154 __ TryAllocate(compiler->float32x4_class(), |
| 2109 slow_path->entry_label(), | 2155 slow_path->entry_label(), |
| 2110 result_reg, | 2156 result_reg, |
| 2111 temp); | 2157 temp); |
| 2112 __ Bind(slow_path->exit_label()); | 2158 __ Bind(slow_path->exit_label()); |
| 2113 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); | 2159 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); |
| 2160 // TODO(zra): Maybe use vldmd here. |
| 2114 __ LoadDFromOffset(value, temp, | 2161 __ LoadDFromOffset(value, temp, |
| 2115 Float32x4::value_offset() - kHeapObjectTag); | 2162 Float32x4::value_offset() - kHeapObjectTag); |
| 2116 __ LoadDFromOffset(value_odd, temp, | 2163 __ LoadDFromOffset(value_odd, temp, |
| 2117 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 2164 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 2118 __ StoreDToOffset(value, result_reg, | 2165 __ StoreDToOffset(value, result_reg, |
| 2119 Float32x4::value_offset() - kHeapObjectTag); | 2166 Float32x4::value_offset() - kHeapObjectTag); |
| 2120 __ StoreDToOffset(value_odd, result_reg, | 2167 __ StoreDToOffset(value_odd, result_reg, |
| 2121 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 2168 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 2122 __ b(&done); | 2169 __ b(&done); |
| 2123 } | 2170 } |
| 2124 | 2171 |
| 2125 __ Bind(&load_pointer); | 2172 __ Bind(&load_pointer); |
| 2126 } | 2173 } |
| 2127 __ LoadFromOffset(kWord, result_reg, | 2174 __ LoadFromOffset(kWord, result_reg, |
| 2128 instance_reg, offset_in_bytes() - kHeapObjectTag); | 2175 instance_reg, offset_in_bytes() - kHeapObjectTag); |
| 2129 __ Bind(&done); | 2176 __ Bind(&done); |
| 2130 } | 2177 } |
| 2131 | 2178 |
| (...skipping 836 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2968 | 3015 |
| 2969 __ TryAllocate(compiler->float32x4_class(), | 3016 __ TryAllocate(compiler->float32x4_class(), |
| 2970 slow_path->entry_label(), | 3017 slow_path->entry_label(), |
| 2971 out_reg, | 3018 out_reg, |
| 2972 locs()->temp(0).reg()); | 3019 locs()->temp(0).reg()); |
| 2973 __ Bind(slow_path->exit_label()); | 3020 __ Bind(slow_path->exit_label()); |
| 2974 | 3021 |
| 2975 __ StoreDToOffset(value_even, out_reg, | 3022 __ StoreDToOffset(value_even, out_reg, |
| 2976 Float32x4::value_offset() - kHeapObjectTag); | 3023 Float32x4::value_offset() - kHeapObjectTag); |
| 2977 __ StoreDToOffset(value_odd, out_reg, | 3024 __ StoreDToOffset(value_odd, out_reg, |
| 2978 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 3025 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 2979 } | 3026 } |
| 2980 | 3027 |
| 2981 | 3028 |
| 2982 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(bool opt) const { | 3029 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(bool opt) const { |
| 2983 const intptr_t value_cid = value()->Type()->ToCid(); | 3030 const intptr_t value_cid = value()->Type()->ToCid(); |
| 2984 const intptr_t kNumInputs = 1; | 3031 const intptr_t kNumInputs = 1; |
| 2985 const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1; | 3032 const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1; |
| 2986 LocationSummary* summary = | 3033 LocationSummary* summary = |
| 2987 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3034 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2988 summary->set_in(0, Location::RequiresRegister()); | 3035 summary->set_in(0, Location::RequiresRegister()); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3004 const Register temp = locs()->temp(0).reg(); | 3051 const Register temp = locs()->temp(0).reg(); |
| 3005 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 3052 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
| 3006 __ tst(value, ShifterOperand(kSmiTagMask)); | 3053 __ tst(value, ShifterOperand(kSmiTagMask)); |
| 3007 __ b(deopt, EQ); | 3054 __ b(deopt, EQ); |
| 3008 __ CompareClassId(value, kFloat32x4Cid, temp); | 3055 __ CompareClassId(value, kFloat32x4Cid, temp); |
| 3009 __ b(deopt, NE); | 3056 __ b(deopt, NE); |
| 3010 } | 3057 } |
| 3011 | 3058 |
| 3012 const DRegister result_even = EvenDRegisterOf(result); | 3059 const DRegister result_even = EvenDRegisterOf(result); |
| 3013 const DRegister result_odd = OddDRegisterOf(result); | 3060 const DRegister result_odd = OddDRegisterOf(result); |
| 3061 // TODO(zra): Maybe use vldmd here. |
| 3014 __ LoadDFromOffset(result_even, value, | 3062 __ LoadDFromOffset(result_even, value, |
| 3015 Float32x4::value_offset() - kHeapObjectTag); | 3063 Float32x4::value_offset() - kHeapObjectTag); |
| 3016 __ LoadDFromOffset(result_odd, value, | 3064 __ LoadDFromOffset(result_odd, value, |
| 3017 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 3065 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 3018 } | 3066 } |
| 3019 | 3067 |
| 3020 | 3068 |
| 3069 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const { |
| 3070 const intptr_t kNumInputs = 1; |
| 3071 const intptr_t kNumTemps = 1; |
| 3072 LocationSummary* summary = |
| 3073 new LocationSummary(kNumInputs, |
| 3074 kNumTemps, |
| 3075 LocationSummary::kCallOnSlowPath); |
| 3076 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3077 summary->set_temp(0, Location::RequiresRegister()); |
| 3078 summary->set_out(Location::RequiresRegister()); |
| 3079 return summary; |
| 3080 } |
| 3081 |
| 3082 |
| 3083 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3084 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); |
| 3085 compiler->AddSlowPathCode(slow_path); |
| 3086 |
| 3087 Register out_reg = locs()->out().reg(); |
| 3088 QRegister value = locs()->in(0).fpu_reg(); |
| 3089 DRegister value_even = EvenDRegisterOf(value); |
| 3090 DRegister value_odd = OddDRegisterOf(value); |
| 3091 |
| 3092 __ TryAllocate(compiler->float64x2_class(), |
| 3093 slow_path->entry_label(), |
| 3094 out_reg, |
| 3095 locs()->temp(0).reg()); |
| 3096 __ Bind(slow_path->exit_label()); |
| 3097 |
| 3098 __ StoreDToOffset(value_even, out_reg, |
| 3099 Float32x4::value_offset() - kHeapObjectTag); |
| 3100 __ StoreDToOffset(value_odd, out_reg, |
| 3101 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 3102 } |
| 3103 |
| 3104 |
| 3105 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(bool opt) const { |
| 3106 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3107 const intptr_t kNumInputs = 1; |
| 3108 const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1; |
| 3109 LocationSummary* summary = |
| 3110 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3111 summary->set_in(0, Location::RequiresRegister()); |
| 3112 if (kNumTemps > 0) { |
| 3113 ASSERT(kNumTemps == 1); |
| 3114 summary->set_temp(0, Location::RequiresRegister()); |
| 3115 } |
| 3116 summary->set_out(Location::RequiresFpuRegister()); |
| 3117 return summary; |
| 3118 } |
| 3119 |
| 3120 |
| 3121 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3122 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3123 const Register value = locs()->in(0).reg(); |
| 3124 const QRegister result = locs()->out().fpu_reg(); |
| 3125 |
| 3126 if (value_cid != kFloat64x2Cid) { |
| 3127 const Register temp = locs()->temp(0).reg(); |
| 3128 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
| 3129 __ tst(value, ShifterOperand(kSmiTagMask)); |
| 3130 __ b(deopt, EQ); |
| 3131 __ CompareClassId(value, kFloat64x2Cid, temp); |
| 3132 __ b(deopt, NE); |
| 3133 } |
| 3134 |
| 3135 const DRegister result_even = EvenDRegisterOf(result); |
| 3136 const DRegister result_odd = OddDRegisterOf(result); |
| 3137 // TODO(zra): Maybe use vldmd here. |
| 3138 __ LoadDFromOffset(result_even, value, |
| 3139 Float64x2::value_offset() - kHeapObjectTag); |
| 3140 __ LoadDFromOffset(result_odd, value, |
| 3141 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 3142 } |
| 3143 |
| 3144 |
| 3021 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const { | 3145 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const { |
| 3022 const intptr_t kNumInputs = 1; | 3146 const intptr_t kNumInputs = 1; |
| 3023 const intptr_t kNumTemps = 1; | 3147 const intptr_t kNumTemps = 1; |
| 3024 LocationSummary* summary = | 3148 LocationSummary* summary = |
| 3025 new LocationSummary(kNumInputs, | 3149 new LocationSummary(kNumInputs, |
| 3026 kNumTemps, | 3150 kNumTemps, |
| 3027 LocationSummary::kCallOnSlowPath); | 3151 LocationSummary::kCallOnSlowPath); |
| 3028 summary->set_in(0, Location::RequiresFpuRegister()); | 3152 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3029 summary->set_temp(0, Location::RequiresRegister()); | 3153 summary->set_temp(0, Location::RequiresRegister()); |
| 3030 summary->set_out(Location::RequiresRegister()); | 3154 summary->set_out(Location::RequiresRegister()); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3074 DRegister value_odd = OddDRegisterOf(value); | 3198 DRegister value_odd = OddDRegisterOf(value); |
| 3075 | 3199 |
| 3076 __ TryAllocate(compiler->int32x4_class(), | 3200 __ TryAllocate(compiler->int32x4_class(), |
| 3077 slow_path->entry_label(), | 3201 slow_path->entry_label(), |
| 3078 out_reg, | 3202 out_reg, |
| 3079 locs()->temp(0).reg()); | 3203 locs()->temp(0).reg()); |
| 3080 __ Bind(slow_path->exit_label()); | 3204 __ Bind(slow_path->exit_label()); |
| 3081 __ StoreDToOffset(value_even, out_reg, | 3205 __ StoreDToOffset(value_even, out_reg, |
| 3082 Int32x4::value_offset() - kHeapObjectTag); | 3206 Int32x4::value_offset() - kHeapObjectTag); |
| 3083 __ StoreDToOffset(value_odd, out_reg, | 3207 __ StoreDToOffset(value_odd, out_reg, |
| 3084 Int32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 3208 Int32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 3085 } | 3209 } |
| 3086 | 3210 |
| 3087 | 3211 |
| 3088 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(bool opt) const { | 3212 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(bool opt) const { |
| 3089 const intptr_t value_cid = value()->Type()->ToCid(); | 3213 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3090 const intptr_t kNumInputs = 1; | 3214 const intptr_t kNumInputs = 1; |
| 3091 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1; | 3215 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1; |
| 3092 LocationSummary* summary = | 3216 LocationSummary* summary = |
| 3093 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3217 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3094 summary->set_in(0, Location::RequiresRegister()); | 3218 summary->set_in(0, Location::RequiresRegister()); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3110 const Register temp = locs()->temp(0).reg(); | 3234 const Register temp = locs()->temp(0).reg(); |
| 3111 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 3235 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
| 3112 __ tst(value, ShifterOperand(kSmiTagMask)); | 3236 __ tst(value, ShifterOperand(kSmiTagMask)); |
| 3113 __ b(deopt, EQ); | 3237 __ b(deopt, EQ); |
| 3114 __ CompareClassId(value, kInt32x4Cid, temp); | 3238 __ CompareClassId(value, kInt32x4Cid, temp); |
| 3115 __ b(deopt, NE); | 3239 __ b(deopt, NE); |
| 3116 } | 3240 } |
| 3117 | 3241 |
| 3118 const DRegister result_even = EvenDRegisterOf(result); | 3242 const DRegister result_even = EvenDRegisterOf(result); |
| 3119 const DRegister result_odd = OddDRegisterOf(result); | 3243 const DRegister result_odd = OddDRegisterOf(result); |
| 3244 // TODO(zra): Maybe use vldmd here. |
| 3120 __ LoadDFromOffset(result_even, value, | 3245 __ LoadDFromOffset(result_even, value, |
| 3121 Int32x4::value_offset() - kHeapObjectTag); | 3246 Int32x4::value_offset() - kHeapObjectTag); |
| 3122 __ LoadDFromOffset(result_odd, value, | 3247 __ LoadDFromOffset(result_odd, value, |
| 3123 Int32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 3248 Int32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 3124 } | 3249 } |
| 3125 | 3250 |
| 3126 | 3251 |
| 3127 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const { | 3252 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const { |
| 3128 const intptr_t kNumInputs = 2; | 3253 const intptr_t kNumInputs = 2; |
| 3129 const intptr_t kNumTemps = 0; | 3254 const intptr_t kNumTemps = 0; |
| 3130 LocationSummary* summary = | 3255 LocationSummary* summary = |
| 3131 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3256 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3132 summary->set_in(0, Location::RequiresFpuRegister()); | 3257 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3133 summary->set_in(1, Location::RequiresFpuRegister()); | 3258 summary->set_in(1, Location::RequiresFpuRegister()); |
| (...skipping 1762 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4896 compiler->GenerateCall(token_pos(), | 5021 compiler->GenerateCall(token_pos(), |
| 4897 &label, | 5022 &label, |
| 4898 PcDescriptors::kOther, | 5023 PcDescriptors::kOther, |
| 4899 locs()); | 5024 locs()); |
| 4900 __ Drop(2); // Discard type arguments and receiver. | 5025 __ Drop(2); // Discard type arguments and receiver. |
| 4901 } | 5026 } |
| 4902 | 5027 |
| 4903 } // namespace dart | 5028 } // namespace dart |
| 4904 | 5029 |
| 4905 #endif // defined TARGET_ARCH_ARM | 5030 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |