| 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 972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 983 (representation() == kUnboxedInt32x4) || | 983 (representation() == kUnboxedInt32x4) || |
| 984 (representation() == kUnboxedFloat64x2)) { | 984 (representation() == kUnboxedFloat64x2)) { |
| 985 locs->set_out(0, Location::RequiresFpuRegister()); | 985 locs->set_out(0, Location::RequiresFpuRegister()); |
| 986 } else { | 986 } else { |
| 987 locs->set_out(0, Location::RequiresRegister()); | 987 locs->set_out(0, Location::RequiresRegister()); |
| 988 } | 988 } |
| 989 return locs; | 989 return locs; |
| 990 } | 990 } |
| 991 | 991 |
| 992 | 992 |
| 993 static Address ElementAddressForIntIndex(bool is_external, | |
| 994 intptr_t cid, | |
| 995 intptr_t index_scale, | |
| 996 Register array, | |
| 997 intptr_t index) { | |
| 998 if (is_external) { | |
| 999 return Address(array, index * index_scale); | |
| 1000 } else { | |
| 1001 const int64_t disp = static_cast<int64_t>(index) * index_scale + | |
| 1002 Instance::DataOffsetFor(cid); | |
| 1003 ASSERT(Utils::IsInt(32, disp)); | |
| 1004 return FieldAddress(array, static_cast<int32_t>(disp)); | |
| 1005 } | |
| 1006 } | |
| 1007 | |
| 1008 | |
| 1009 static ScaleFactor ToScaleFactor(intptr_t index_scale) { | |
| 1010 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays with | |
| 1011 // index scale factor > 1. E.g., for Uint8Array and OneByteString the index is | |
| 1012 // expected to be untagged before accessing. | |
| 1013 ASSERT(kSmiTagShift == 1); | |
| 1014 switch (index_scale) { | |
| 1015 case 1: return TIMES_1; | |
| 1016 case 2: return TIMES_1; | |
| 1017 case 4: return TIMES_2; | |
| 1018 case 8: return TIMES_4; | |
| 1019 case 16: return TIMES_8; | |
| 1020 default: | |
| 1021 UNREACHABLE(); | |
| 1022 return TIMES_1; | |
| 1023 } | |
| 1024 } | |
| 1025 | |
| 1026 | |
| 1027 static Address ElementAddressForRegIndex(bool is_external, | |
| 1028 intptr_t cid, | |
| 1029 intptr_t index_scale, | |
| 1030 Register array, | |
| 1031 Register index) { | |
| 1032 if (is_external) { | |
| 1033 return Address(array, index, ToScaleFactor(index_scale), 0); | |
| 1034 } else { | |
| 1035 return FieldAddress(array, | |
| 1036 index, | |
| 1037 ToScaleFactor(index_scale), | |
| 1038 Instance::DataOffsetFor(cid)); | |
| 1039 } | |
| 1040 } | |
| 1041 | |
| 1042 | |
| 1043 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 993 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1044 // The array register points to the backing store for external arrays. | 994 // The array register points to the backing store for external arrays. |
| 1045 const Register array = locs()->in(0).reg(); | 995 const Register array = locs()->in(0).reg(); |
| 1046 const Location index = locs()->in(1); | 996 const Location index = locs()->in(1); |
| 1047 | 997 |
| 1048 Address element_address = index.IsRegister() | 998 Address element_address = index.IsRegister() |
| 1049 ? ElementAddressForRegIndex(IsExternal(), class_id(), index_scale(), | 999 ? Assembler::ElementAddressForRegIndex( |
| 1050 array, index.reg()) | 1000 IsExternal(), class_id(), index_scale(), array, index.reg()) |
| 1051 : ElementAddressForIntIndex(IsExternal(), class_id(), index_scale(), | 1001 : Assembler::ElementAddressForIntIndex( |
| 1052 array, Smi::Cast(index.constant()).Value()); | 1002 IsExternal(), class_id(), index_scale(), |
| 1003 array, Smi::Cast(index.constant()).Value()); |
| 1053 | 1004 |
| 1054 if ((representation() == kUnboxedDouble) || | 1005 if ((representation() == kUnboxedDouble) || |
| 1055 (representation() == kUnboxedFloat32x4) || | 1006 (representation() == kUnboxedFloat32x4) || |
| 1056 (representation() == kUnboxedInt32x4) || | 1007 (representation() == kUnboxedInt32x4) || |
| 1057 (representation() == kUnboxedFloat64x2)) { | 1008 (representation() == kUnboxedFloat64x2)) { |
| 1058 if ((index_scale() == 1) && index.IsRegister()) { | 1009 if ((index_scale() == 1) && index.IsRegister()) { |
| 1059 __ SmiUntag(index.reg()); | 1010 __ SmiUntag(index.reg()); |
| 1060 } | 1011 } |
| 1061 | 1012 |
| 1062 XmmRegister result = locs()->out(0).fpu_reg(); | 1013 XmmRegister result = locs()->out(0).fpu_reg(); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1210 return locs; | 1161 return locs; |
| 1211 } | 1162 } |
| 1212 | 1163 |
| 1213 | 1164 |
| 1214 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1165 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1215 // The array register points to the backing store for external arrays. | 1166 // The array register points to the backing store for external arrays. |
| 1216 const Register array = locs()->in(0).reg(); | 1167 const Register array = locs()->in(0).reg(); |
| 1217 const Location index = locs()->in(1); | 1168 const Location index = locs()->in(1); |
| 1218 | 1169 |
| 1219 Address element_address = index.IsRegister() | 1170 Address element_address = index.IsRegister() |
| 1220 ? ElementAddressForRegIndex(IsExternal(), class_id(), index_scale(), | 1171 ? Assembler::ElementAddressForRegIndex( |
| 1221 array, index.reg()) | 1172 IsExternal(), class_id(), index_scale(), array, index.reg()) |
| 1222 : ElementAddressForIntIndex(IsExternal(), class_id(), index_scale(), | 1173 : Assembler::ElementAddressForIntIndex( |
| 1223 array, Smi::Cast(index.constant()).Value()); | 1174 IsExternal(), class_id(), index_scale(), |
| 1175 array, Smi::Cast(index.constant()).Value()); |
| 1224 | 1176 |
| 1225 if ((index_scale() == 1) && index.IsRegister()) { | 1177 if ((index_scale() == 1) && index.IsRegister()) { |
| 1226 __ SmiUntag(index.reg()); | 1178 __ SmiUntag(index.reg()); |
| 1227 } | 1179 } |
| 1228 switch (class_id()) { | 1180 switch (class_id()) { |
| 1229 case kArrayCid: | 1181 case kArrayCid: |
| 1230 if (ShouldEmitStoreBarrier()) { | 1182 if (ShouldEmitStoreBarrier()) { |
| 1231 Register value = locs()->in(2).reg(); | 1183 Register value = locs()->in(2).reg(); |
| 1232 __ StoreIntoObject(array, element_address, value); | 1184 __ StoreIntoObject(array, element_address, value); |
| 1233 } else if (locs()->in(2).IsConstant()) { | 1185 } else if (locs()->in(2).IsConstant()) { |
| (...skipping 4776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6010 __ movq(R10, Immediate(kInvalidObjectPointer)); | 5962 __ movq(R10, Immediate(kInvalidObjectPointer)); |
| 6011 __ movq(RBX, Immediate(kInvalidObjectPointer)); | 5963 __ movq(RBX, Immediate(kInvalidObjectPointer)); |
| 6012 #endif | 5964 #endif |
| 6013 } | 5965 } |
| 6014 | 5966 |
| 6015 } // namespace dart | 5967 } // namespace dart |
| 6016 | 5968 |
| 6017 #undef __ | 5969 #undef __ |
| 6018 | 5970 |
| 6019 #endif // defined TARGET_ARCH_X64 | 5971 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |