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 |