| 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 "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 954 Register result = locs()->out().reg(); | 954 Register result = locs()->out().reg(); |
| 955 __ movq(result, | 955 __ movq(result, |
| 956 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress()))); | 956 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress()))); |
| 957 __ movq(result, Address(result, | 957 __ movq(result, Address(result, |
| 958 char_code, | 958 char_code, |
| 959 TIMES_HALF_WORD_SIZE, // Char code is a smi. | 959 TIMES_HALF_WORD_SIZE, // Char code is a smi. |
| 960 Symbols::kNullCharCodeSymbolOffset * kWordSize)); | 960 Symbols::kNullCharCodeSymbolOffset * kWordSize)); |
| 961 } | 961 } |
| 962 | 962 |
| 963 | 963 |
| 964 LocationSummary* LoadUntaggedInstr::MakeLocationSummary() const { |
| 965 const intptr_t kNumInputs = 1; |
| 966 const intptr_t kNumTemps = 0; |
| 967 LocationSummary* locs = |
| 968 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 969 locs->set_in(0, Location::RequiresRegister()); |
| 970 locs->set_out(Location::RequiresRegister()); |
| 971 return locs; |
| 972 } |
| 973 |
| 974 |
| 975 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 976 Register object = locs()->in(0).reg(); |
| 977 Register result = locs()->out().reg(); |
| 978 __ movq(result, FieldAddress(object, offset())); |
| 979 } |
| 980 |
| 981 |
| 964 CompileType LoadIndexedInstr::ComputeType() const { | 982 CompileType LoadIndexedInstr::ComputeType() const { |
| 965 switch (class_id_) { | 983 switch (class_id_) { |
| 966 case kArrayCid: | 984 case kArrayCid: |
| 967 case kImmutableArrayCid: | 985 case kImmutableArrayCid: |
| 968 return CompileType::Dynamic(); | 986 return CompileType::Dynamic(); |
| 969 | 987 |
| 970 case kFloat32ArrayCid: | |
| 971 case kFloat64ArrayCid: | |
| 972 case kTypedDataFloat32ArrayCid: | 988 case kTypedDataFloat32ArrayCid: |
| 973 case kTypedDataFloat64ArrayCid: | 989 case kTypedDataFloat64ArrayCid: |
| 974 return CompileType::FromCid(kDoubleCid); | 990 return CompileType::FromCid(kDoubleCid); |
| 975 | 991 |
| 976 case kInt8ArrayCid: | |
| 977 case kUint8ArrayCid: | |
| 978 case kUint8ClampedArrayCid: | |
| 979 case kExternalUint8ArrayCid: | |
| 980 case kExternalUint8ClampedArrayCid: | |
| 981 case kInt16ArrayCid: | |
| 982 case kUint16ArrayCid: | |
| 983 case kTypedDataInt8ArrayCid: | 992 case kTypedDataInt8ArrayCid: |
| 984 case kTypedDataUint8ArrayCid: | 993 case kTypedDataUint8ArrayCid: |
| 985 case kTypedDataUint8ClampedArrayCid: | 994 case kTypedDataUint8ClampedArrayCid: |
| 986 case kExternalTypedDataUint8ArrayCid: | 995 case kExternalTypedDataUint8ArrayCid: |
| 987 case kExternalTypedDataUint8ClampedArrayCid: | 996 case kExternalTypedDataUint8ClampedArrayCid: |
| 988 case kTypedDataInt16ArrayCid: | 997 case kTypedDataInt16ArrayCid: |
| 989 case kTypedDataUint16ArrayCid: | 998 case kTypedDataUint16ArrayCid: |
| 990 case kOneByteStringCid: | 999 case kOneByteStringCid: |
| 991 case kTwoByteStringCid: | 1000 case kTwoByteStringCid: |
| 992 case kInt32ArrayCid: | |
| 993 case kUint32ArrayCid: | |
| 994 case kTypedDataInt32ArrayCid: | 1001 case kTypedDataInt32ArrayCid: |
| 995 case kTypedDataUint32ArrayCid: | 1002 case kTypedDataUint32ArrayCid: |
| 996 return CompileType::FromCid(kSmiCid); | 1003 return CompileType::FromCid(kSmiCid); |
| 997 | 1004 |
| 998 default: | 1005 default: |
| 999 UNIMPLEMENTED(); | 1006 UNIMPLEMENTED(); |
| 1000 return CompileType::Dynamic(); | 1007 return CompileType::Dynamic(); |
| 1001 } | 1008 } |
| 1002 } | 1009 } |
| 1003 | 1010 |
| 1004 | 1011 |
| 1005 Representation LoadIndexedInstr::representation() const { | 1012 Representation LoadIndexedInstr::representation() const { |
| 1006 switch (class_id_) { | 1013 switch (class_id_) { |
| 1007 case kArrayCid: | 1014 case kArrayCid: |
| 1008 case kImmutableArrayCid: | 1015 case kImmutableArrayCid: |
| 1009 case kInt8ArrayCid: | |
| 1010 case kUint8ArrayCid: | |
| 1011 case kUint8ClampedArrayCid: | |
| 1012 case kExternalUint8ArrayCid: | |
| 1013 case kExternalUint8ClampedArrayCid: | |
| 1014 case kInt16ArrayCid: | |
| 1015 case kUint16ArrayCid: | |
| 1016 case kTypedDataInt8ArrayCid: | 1016 case kTypedDataInt8ArrayCid: |
| 1017 case kTypedDataUint8ArrayCid: | 1017 case kTypedDataUint8ArrayCid: |
| 1018 case kTypedDataUint8ClampedArrayCid: | 1018 case kTypedDataUint8ClampedArrayCid: |
| 1019 case kExternalTypedDataUint8ArrayCid: | 1019 case kExternalTypedDataUint8ArrayCid: |
| 1020 case kExternalTypedDataUint8ClampedArrayCid: | 1020 case kExternalTypedDataUint8ClampedArrayCid: |
| 1021 case kTypedDataInt16ArrayCid: | 1021 case kTypedDataInt16ArrayCid: |
| 1022 case kTypedDataUint16ArrayCid: | 1022 case kTypedDataUint16ArrayCid: |
| 1023 case kOneByteStringCid: | 1023 case kOneByteStringCid: |
| 1024 case kTwoByteStringCid: | 1024 case kTwoByteStringCid: |
| 1025 case kInt32ArrayCid: | |
| 1026 case kUint32ArrayCid: | |
| 1027 case kTypedDataInt32ArrayCid: | 1025 case kTypedDataInt32ArrayCid: |
| 1028 case kTypedDataUint32ArrayCid: | 1026 case kTypedDataUint32ArrayCid: |
| 1029 return kTagged; | 1027 return kTagged; |
| 1030 case kFloat32ArrayCid : | |
| 1031 case kFloat64ArrayCid : | |
| 1032 case kTypedDataFloat32ArrayCid: | 1028 case kTypedDataFloat32ArrayCid: |
| 1033 case kTypedDataFloat64ArrayCid: | 1029 case kTypedDataFloat64ArrayCid: |
| 1034 return kUnboxedDouble; | 1030 return kUnboxedDouble; |
| 1035 default: | 1031 default: |
| 1036 UNIMPLEMENTED(); | 1032 UNIMPLEMENTED(); |
| 1037 return kTagged; | 1033 return kTagged; |
| 1038 } | 1034 } |
| 1039 } | 1035 } |
| 1040 | 1036 |
| 1041 | 1037 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1064 locs->set_out(Location::RequiresRegister()); | 1060 locs->set_out(Location::RequiresRegister()); |
| 1065 } | 1061 } |
| 1066 return locs; | 1062 return locs; |
| 1067 } | 1063 } |
| 1068 | 1064 |
| 1069 | 1065 |
| 1070 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1066 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1071 Register array = locs()->in(0).reg(); | 1067 Register array = locs()->in(0).reg(); |
| 1072 Location index = locs()->in(1); | 1068 Location index = locs()->in(1); |
| 1073 | 1069 |
| 1074 if ((class_id() == kExternalUint8ArrayCid) || | 1070 const bool is_external = |
| 1075 (class_id() == kExternalUint8ClampedArrayCid) || | 1071 (this->array()->definition()->representation() == kUntagged); |
| 1076 (class_id() == kExternalTypedDataUint8ArrayCid) || | 1072 Address element_address(kNoRegister, 0); |
| 1077 (class_id() == kExternalTypedDataUint8ClampedArrayCid)) { | 1073 |
| 1078 Register result = locs()->out().reg(); | 1074 if (is_external) { |
| 1079 Address element_address = index.IsRegister() | 1075 element_address = index.IsRegister() |
| 1080 ? FlowGraphCompiler::ExternalElementAddressForRegIndex( | 1076 ? FlowGraphCompiler::ExternalElementAddressForRegIndex( |
| 1081 index_scale(), result, index.reg()) | 1077 index_scale(), array, index.reg()) |
| 1082 : FlowGraphCompiler::ExternalElementAddressForIntIndex( | 1078 : FlowGraphCompiler::ExternalElementAddressForIntIndex( |
| 1083 index_scale(), result, Smi::Cast(index.constant()).Value()); | 1079 index_scale(), array, Smi::Cast(index.constant()).Value()); |
| 1084 ASSERT(index_scale() == 1); | 1080 } else { |
| 1085 if (index.IsRegister()) { | 1081 ASSERT(this->array()->definition()->representation() == kTagged); |
| 1086 __ SmiUntag(index.reg()); | 1082 element_address = index.IsRegister() |
| 1087 } | 1083 ? FlowGraphCompiler::ElementAddressForRegIndex( |
| 1088 __ movq(result, | 1084 class_id(), index_scale(), array, index.reg()) |
| 1089 FieldAddress(array, ExternalUint8Array::data_offset())); | 1085 : FlowGraphCompiler::ElementAddressForIntIndex( |
| 1090 __ movzxb(result, element_address); | 1086 class_id(), index_scale(), array, |
| 1091 __ SmiTag(result); | 1087 Smi::Cast(index.constant()).Value()); |
| 1092 return; | |
| 1093 } | 1088 } |
| 1094 | 1089 |
| 1095 FieldAddress element_address = index.IsRegister() | |
| 1096 ? FlowGraphCompiler::ElementAddressForRegIndex( | |
| 1097 class_id(), index_scale(), array, index.reg()) | |
| 1098 : FlowGraphCompiler::ElementAddressForIntIndex( | |
| 1099 class_id(), index_scale(), array, | |
| 1100 Smi::Cast(index.constant()).Value()); | |
| 1101 | |
| 1102 if (representation() == kUnboxedDouble) { | 1090 if (representation() == kUnboxedDouble) { |
| 1103 if ((index_scale() == 1) && index.IsRegister()) { | 1091 if ((index_scale() == 1) && index.IsRegister()) { |
| 1104 __ SmiUntag(index.reg()); | 1092 __ SmiUntag(index.reg()); |
| 1105 } | 1093 } |
| 1106 | 1094 |
| 1107 XmmRegister result = locs()->out().fpu_reg(); | 1095 XmmRegister result = locs()->out().fpu_reg(); |
| 1108 if (class_id() == kFloat32ArrayCid || | 1096 if (class_id() == kTypedDataFloat32ArrayCid) { |
| 1109 class_id() == kTypedDataFloat32ArrayCid) { | |
| 1110 // Load single precision float. | 1097 // Load single precision float. |
| 1111 __ movss(result, element_address); | 1098 __ movss(result, element_address); |
| 1112 // Promote to double. | 1099 // Promote to double. |
| 1113 __ cvtss2sd(result, locs()->out().fpu_reg()); | 1100 __ cvtss2sd(result, locs()->out().fpu_reg()); |
| 1114 } else { | 1101 } else { |
| 1115 ASSERT(class_id() == kFloat64ArrayCid || | 1102 ASSERT(class_id() == kTypedDataFloat64ArrayCid); |
| 1116 class_id() == kTypedDataFloat64ArrayCid); | |
| 1117 __ movsd(result, element_address); | 1103 __ movsd(result, element_address); |
| 1118 } | 1104 } |
| 1119 return; | 1105 return; |
| 1120 } | 1106 } |
| 1121 | 1107 |
| 1122 if ((index_scale() == 1) && index.IsRegister()) { | 1108 if ((index_scale() == 1) && index.IsRegister()) { |
| 1123 __ SmiUntag(index.reg()); | 1109 __ SmiUntag(index.reg()); |
| 1124 } | 1110 } |
| 1125 Register result = locs()->out().reg(); | 1111 Register result = locs()->out().reg(); |
| 1126 switch (class_id()) { | 1112 switch (class_id()) { |
| 1127 case kInt8ArrayCid: | |
| 1128 case kTypedDataInt8ArrayCid: | 1113 case kTypedDataInt8ArrayCid: |
| 1129 __ movsxb(result, element_address); | 1114 __ movsxb(result, element_address); |
| 1130 __ SmiTag(result); | 1115 __ SmiTag(result); |
| 1131 break; | 1116 break; |
| 1132 case kUint8ArrayCid: | |
| 1133 case kUint8ClampedArrayCid: | |
| 1134 case kTypedDataUint8ArrayCid: | 1117 case kTypedDataUint8ArrayCid: |
| 1135 case kTypedDataUint8ClampedArrayCid: | 1118 case kTypedDataUint8ClampedArrayCid: |
| 1119 case kExternalTypedDataUint8ArrayCid: |
| 1120 case kExternalTypedDataUint8ClampedArrayCid: |
| 1136 case kOneByteStringCid: | 1121 case kOneByteStringCid: |
| 1137 __ movzxb(result, element_address); | 1122 __ movzxb(result, element_address); |
| 1138 __ SmiTag(result); | 1123 __ SmiTag(result); |
| 1139 break; | 1124 break; |
| 1140 case kInt16ArrayCid: | |
| 1141 case kTypedDataInt16ArrayCid: | 1125 case kTypedDataInt16ArrayCid: |
| 1142 __ movsxw(result, element_address); | 1126 __ movsxw(result, element_address); |
| 1143 __ SmiTag(result); | 1127 __ SmiTag(result); |
| 1144 break; | 1128 break; |
| 1145 case kUint16ArrayCid: | |
| 1146 case kTypedDataUint16ArrayCid: | 1129 case kTypedDataUint16ArrayCid: |
| 1147 case kTwoByteStringCid: | 1130 case kTwoByteStringCid: |
| 1148 __ movzxw(result, element_address); | 1131 __ movzxw(result, element_address); |
| 1149 __ SmiTag(result); | 1132 __ SmiTag(result); |
| 1150 break; | 1133 break; |
| 1151 case kInt32ArrayCid: | |
| 1152 case kTypedDataInt32ArrayCid: | 1134 case kTypedDataInt32ArrayCid: |
| 1153 __ movsxl(result, element_address); | 1135 __ movsxl(result, element_address); |
| 1154 __ SmiTag(result); | 1136 __ SmiTag(result); |
| 1155 break; | 1137 break; |
| 1156 case kUint32ArrayCid: | |
| 1157 case kTypedDataUint32ArrayCid: | 1138 case kTypedDataUint32ArrayCid: |
| 1158 __ movl(result, element_address); | 1139 __ movl(result, element_address); |
| 1159 __ SmiTag(result); | 1140 __ SmiTag(result); |
| 1160 break; | 1141 break; |
| 1161 default: | 1142 default: |
| 1162 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); | 1143 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); |
| 1163 __ movq(result, element_address); | 1144 __ movq(result, element_address); |
| 1164 break; | 1145 break; |
| 1165 } | 1146 } |
| 1166 } | 1147 } |
| 1167 | 1148 |
| 1168 | 1149 |
| 1169 Representation StoreIndexedInstr::RequiredInputRepresentation( | 1150 Representation StoreIndexedInstr::RequiredInputRepresentation( |
| 1170 intptr_t idx) const { | 1151 intptr_t idx) const { |
| 1171 if ((idx == 0) || (idx == 1)) return kTagged; | 1152 if (idx == 0) return kNoRepresentation; |
| 1153 if (idx == 1) return kTagged; |
| 1172 ASSERT(idx == 2); | 1154 ASSERT(idx == 2); |
| 1173 switch (class_id_) { | 1155 switch (class_id_) { |
| 1174 case kArrayCid: | 1156 case kArrayCid: |
| 1175 case kInt8ArrayCid: | |
| 1176 case kUint8ArrayCid: | |
| 1177 case kExternalUint8ArrayCid: | |
| 1178 case kUint8ClampedArrayCid: | |
| 1179 case kExternalUint8ClampedArrayCid: | |
| 1180 case kInt16ArrayCid: | |
| 1181 case kUint16ArrayCid: | |
| 1182 case kInt32ArrayCid: | |
| 1183 case kUint32ArrayCid: | |
| 1184 case kTypedDataInt8ArrayCid: | 1157 case kTypedDataInt8ArrayCid: |
| 1185 case kTypedDataUint8ArrayCid: | 1158 case kTypedDataUint8ArrayCid: |
| 1186 case kExternalTypedDataUint8ArrayCid: | 1159 case kExternalTypedDataUint8ArrayCid: |
| 1187 case kTypedDataUint8ClampedArrayCid: | 1160 case kTypedDataUint8ClampedArrayCid: |
| 1188 case kExternalTypedDataUint8ClampedArrayCid: | 1161 case kExternalTypedDataUint8ClampedArrayCid: |
| 1189 case kTypedDataInt16ArrayCid: | 1162 case kTypedDataInt16ArrayCid: |
| 1190 case kTypedDataUint16ArrayCid: | 1163 case kTypedDataUint16ArrayCid: |
| 1191 case kTypedDataInt32ArrayCid: | 1164 case kTypedDataInt32ArrayCid: |
| 1192 case kTypedDataUint32ArrayCid: | 1165 case kTypedDataUint32ArrayCid: |
| 1193 return kTagged; | 1166 return kTagged; |
| 1194 case kFloat32ArrayCid: | |
| 1195 case kFloat64ArrayCid: | |
| 1196 case kTypedDataFloat32ArrayCid: | 1167 case kTypedDataFloat32ArrayCid: |
| 1197 case kTypedDataFloat64ArrayCid: | 1168 case kTypedDataFloat64ArrayCid: |
| 1198 return kUnboxedDouble; | 1169 return kUnboxedDouble; |
| 1199 default: | 1170 default: |
| 1200 UNIMPLEMENTED(); | 1171 UNIMPLEMENTED(); |
| 1201 return kTagged; | 1172 return kTagged; |
| 1202 } | 1173 } |
| 1203 } | 1174 } |
| 1204 | 1175 |
| 1205 | 1176 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1221 ? Location::Constant( | 1192 ? Location::Constant( |
| 1222 index()->definition()->AsConstant()->value()) | 1193 index()->definition()->AsConstant()->value()) |
| 1223 : Location::RequiresRegister()); | 1194 : Location::RequiresRegister()); |
| 1224 } | 1195 } |
| 1225 switch (class_id()) { | 1196 switch (class_id()) { |
| 1226 case kArrayCid: | 1197 case kArrayCid: |
| 1227 locs->set_in(2, ShouldEmitStoreBarrier() | 1198 locs->set_in(2, ShouldEmitStoreBarrier() |
| 1228 ? Location::WritableRegister() | 1199 ? Location::WritableRegister() |
| 1229 : Location::RegisterOrConstant(value())); | 1200 : Location::RegisterOrConstant(value())); |
| 1230 break; | 1201 break; |
| 1231 case kExternalUint8ArrayCid: | |
| 1232 case kExternalUint8ClampedArrayCid: | |
| 1233 case kExternalTypedDataUint8ArrayCid: | 1202 case kExternalTypedDataUint8ArrayCid: |
| 1234 case kExternalTypedDataUint8ClampedArrayCid: | 1203 case kExternalTypedDataUint8ClampedArrayCid: |
| 1235 // Need temp register to load the external array's data array. | |
| 1236 locs->AddTemp(Location::RequiresRegister()); | |
| 1237 // Fall through. | |
| 1238 case kInt8ArrayCid: | |
| 1239 case kUint8ArrayCid: | |
| 1240 case kUint8ClampedArrayCid: | |
| 1241 case kTypedDataInt8ArrayCid: | 1204 case kTypedDataInt8ArrayCid: |
| 1242 case kTypedDataUint8ArrayCid: | 1205 case kTypedDataUint8ArrayCid: |
| 1243 case kTypedDataUint8ClampedArrayCid: | 1206 case kTypedDataUint8ClampedArrayCid: |
| 1244 // TODO(fschneider): Add location constraint for byte registers (RAX, | 1207 // TODO(fschneider): Add location constraint for byte registers (RAX, |
| 1245 // RBX, RCX, RDX) instead of using a fixed register. | 1208 // RBX, RCX, RDX) instead of using a fixed register. |
| 1246 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), RAX)); | 1209 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), RAX)); |
| 1247 break; | 1210 break; |
| 1248 case kInt16ArrayCid: | |
| 1249 case kUint16ArrayCid: | |
| 1250 case kInt32ArrayCid: | |
| 1251 case kUint32ArrayCid: | |
| 1252 case kTypedDataInt16ArrayCid: | 1211 case kTypedDataInt16ArrayCid: |
| 1253 case kTypedDataUint16ArrayCid: | 1212 case kTypedDataUint16ArrayCid: |
| 1254 case kTypedDataInt32ArrayCid: | 1213 case kTypedDataInt32ArrayCid: |
| 1255 case kTypedDataUint32ArrayCid: | 1214 case kTypedDataUint32ArrayCid: |
| 1256 // Writable register because the value must be untagged before storing. | 1215 // Writable register because the value must be untagged before storing. |
| 1257 locs->set_in(2, Location::WritableRegister()); | 1216 locs->set_in(2, Location::WritableRegister()); |
| 1258 break; | 1217 break; |
| 1259 case kFloat32ArrayCid: | |
| 1260 case kTypedDataFloat32ArrayCid: | 1218 case kTypedDataFloat32ArrayCid: |
| 1261 // Need temp register for float-to-double conversion. | 1219 // Need temp register for float-to-double conversion. |
| 1262 locs->AddTemp(Location::RequiresFpuRegister()); | 1220 locs->AddTemp(Location::RequiresFpuRegister()); |
| 1263 // Fall through. | 1221 // Fall through. |
| 1264 case kFloat64ArrayCid: | |
| 1265 case kTypedDataFloat64ArrayCid: | 1222 case kTypedDataFloat64ArrayCid: |
| 1266 // TODO(srdjan): Support Float64 constants. | 1223 // TODO(srdjan): Support Float64 constants. |
| 1267 locs->set_in(2, Location::RequiresFpuRegister()); | 1224 locs->set_in(2, Location::RequiresFpuRegister()); |
| 1268 break; | 1225 break; |
| 1269 default: | 1226 default: |
| 1270 UNREACHABLE(); | 1227 UNREACHABLE(); |
| 1271 return NULL; | 1228 return NULL; |
| 1272 } | 1229 } |
| 1273 return locs; | 1230 return locs; |
| 1274 } | 1231 } |
| 1275 | 1232 |
| 1276 | 1233 |
| 1277 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1234 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1278 Register array = locs()->in(0).reg(); | 1235 Register array = locs()->in(0).reg(); |
| 1279 Location index = locs()->in(1); | 1236 Location index = locs()->in(1); |
| 1280 | 1237 |
| 1238 const bool is_external = |
| 1239 (this->array()->definition()->representation() == kUntagged); |
| 1281 Address element_address(kNoRegister, 0); | 1240 Address element_address(kNoRegister, 0); |
| 1282 if ((class_id() == kExternalUint8ArrayCid) || | 1241 if (is_external) { |
| 1283 (class_id() == kExternalUint8ClampedArrayCid) || | |
| 1284 (class_id() == kExternalTypedDataUint8ArrayCid) || | |
| 1285 (class_id() == kExternalTypedDataUint8ClampedArrayCid)) { | |
| 1286 Register temp = locs()->temp(0).reg(); | |
| 1287 element_address = index.IsRegister() | 1242 element_address = index.IsRegister() |
| 1288 ? FlowGraphCompiler::ExternalElementAddressForRegIndex( | 1243 ? FlowGraphCompiler::ExternalElementAddressForRegIndex( |
| 1289 index_scale(), temp, index.reg()) | 1244 index_scale(), array, index.reg()) |
| 1290 : FlowGraphCompiler::ExternalElementAddressForIntIndex( | 1245 : FlowGraphCompiler::ExternalElementAddressForIntIndex( |
| 1291 index_scale(), temp, Smi::Cast(index.constant()).Value()); | 1246 index_scale(), array, Smi::Cast(index.constant()).Value()); |
| 1292 __ movq(temp, | |
| 1293 FieldAddress(array, ExternalUint8Array::data_offset())); | |
| 1294 } else { | 1247 } else { |
| 1248 ASSERT(this->array()->definition()->representation() == kTagged); |
| 1295 element_address = index.IsRegister() | 1249 element_address = index.IsRegister() |
| 1296 ? FlowGraphCompiler::ElementAddressForRegIndex( | 1250 ? FlowGraphCompiler::ElementAddressForRegIndex( |
| 1297 class_id(), index_scale(), array, index.reg()) | 1251 class_id(), index_scale(), array, index.reg()) |
| 1298 : FlowGraphCompiler::ElementAddressForIntIndex( | 1252 : FlowGraphCompiler::ElementAddressForIntIndex( |
| 1299 class_id(), index_scale(), array, | 1253 class_id(), index_scale(), array, |
| 1300 Smi::Cast(index.constant()).Value()); | 1254 Smi::Cast(index.constant()).Value()); |
| 1301 } | 1255 } |
| 1302 | 1256 |
| 1303 if ((index_scale() == 1) && index.IsRegister()) { | 1257 if ((index_scale() == 1) && index.IsRegister()) { |
| 1304 __ SmiUntag(index.reg()); | 1258 __ SmiUntag(index.reg()); |
| 1305 } | 1259 } |
| 1306 switch (class_id()) { | 1260 switch (class_id()) { |
| 1307 case kArrayCid: | 1261 case kArrayCid: |
| 1308 if (ShouldEmitStoreBarrier()) { | 1262 if (ShouldEmitStoreBarrier()) { |
| 1309 Register value = locs()->in(2).reg(); | 1263 Register value = locs()->in(2).reg(); |
| 1310 __ StoreIntoObject(array, element_address, value); | 1264 __ StoreIntoObject(array, element_address, value); |
| 1311 } else if (locs()->in(2).IsConstant()) { | 1265 } else if (locs()->in(2).IsConstant()) { |
| 1312 const Object& constant = locs()->in(2).constant(); | 1266 const Object& constant = locs()->in(2).constant(); |
| 1313 __ StoreObject(element_address, constant); | 1267 __ StoreObject(element_address, constant); |
| 1314 } else { | 1268 } else { |
| 1315 Register value = locs()->in(2).reg(); | 1269 Register value = locs()->in(2).reg(); |
| 1316 __ StoreIntoObjectNoBarrier(array, element_address, value); | 1270 __ StoreIntoObjectNoBarrier(array, element_address, value); |
| 1317 } | 1271 } |
| 1318 break; | 1272 break; |
| 1319 case kInt8ArrayCid: | |
| 1320 case kUint8ArrayCid: | |
| 1321 case kExternalUint8ArrayCid: | |
| 1322 case kTypedDataInt8ArrayCid: | 1273 case kTypedDataInt8ArrayCid: |
| 1323 case kTypedDataUint8ArrayCid: | 1274 case kTypedDataUint8ArrayCid: |
| 1324 case kExternalTypedDataUint8ArrayCid: | 1275 case kExternalTypedDataUint8ArrayCid: |
| 1325 if (locs()->in(2).IsConstant()) { | 1276 if (locs()->in(2).IsConstant()) { |
| 1326 const Smi& constant = Smi::Cast(locs()->in(2).constant()); | 1277 const Smi& constant = Smi::Cast(locs()->in(2).constant()); |
| 1327 __ movb(element_address, | 1278 __ movb(element_address, |
| 1328 Immediate(static_cast<int8_t>(constant.Value()))); | 1279 Immediate(static_cast<int8_t>(constant.Value()))); |
| 1329 } else { | 1280 } else { |
| 1330 ASSERT(locs()->in(2).reg() == RAX); | 1281 ASSERT(locs()->in(2).reg() == RAX); |
| 1331 __ SmiUntag(RAX); | 1282 __ SmiUntag(RAX); |
| 1332 __ movb(element_address, RAX); | 1283 __ movb(element_address, RAX); |
| 1333 } | 1284 } |
| 1334 break; | 1285 break; |
| 1335 case kUint8ClampedArrayCid: | |
| 1336 case kExternalUint8ClampedArrayCid: | |
| 1337 case kTypedDataUint8ClampedArrayCid: | 1286 case kTypedDataUint8ClampedArrayCid: |
| 1338 case kExternalTypedDataUint8ClampedArrayCid: { | 1287 case kExternalTypedDataUint8ClampedArrayCid: { |
| 1339 if (locs()->in(2).IsConstant()) { | 1288 if (locs()->in(2).IsConstant()) { |
| 1340 const Smi& constant = Smi::Cast(locs()->in(2).constant()); | 1289 const Smi& constant = Smi::Cast(locs()->in(2).constant()); |
| 1341 intptr_t value = constant.Value(); | 1290 intptr_t value = constant.Value(); |
| 1342 // Clamp to 0x0 or 0xFF respectively. | 1291 // Clamp to 0x0 or 0xFF respectively. |
| 1343 if (value > 0xFF) { | 1292 if (value > 0xFF) { |
| 1344 value = 0xFF; | 1293 value = 0xFF; |
| 1345 } else if (value < 0) { | 1294 } else if (value < 0) { |
| 1346 value = 0; | 1295 value = 0; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1357 __ j(GREATER, &store_0xff); | 1306 __ j(GREATER, &store_0xff); |
| 1358 __ xorq(RAX, RAX); | 1307 __ xorq(RAX, RAX); |
| 1359 __ jmp(&store_value, Assembler::kNearJump); | 1308 __ jmp(&store_value, Assembler::kNearJump); |
| 1360 __ Bind(&store_0xff); | 1309 __ Bind(&store_0xff); |
| 1361 __ movq(RAX, Immediate(0xFF)); | 1310 __ movq(RAX, Immediate(0xFF)); |
| 1362 __ Bind(&store_value); | 1311 __ Bind(&store_value); |
| 1363 __ movb(element_address, RAX); | 1312 __ movb(element_address, RAX); |
| 1364 } | 1313 } |
| 1365 break; | 1314 break; |
| 1366 } | 1315 } |
| 1367 case kInt16ArrayCid: | |
| 1368 case kUint16ArrayCid: | |
| 1369 case kTypedDataInt16ArrayCid: | 1316 case kTypedDataInt16ArrayCid: |
| 1370 case kTypedDataUint16ArrayCid: { | 1317 case kTypedDataUint16ArrayCid: { |
| 1371 Register value = locs()->in(2).reg(); | 1318 Register value = locs()->in(2).reg(); |
| 1372 __ SmiUntag(value); | 1319 __ SmiUntag(value); |
| 1373 __ movw(element_address, value); | 1320 __ movw(element_address, value); |
| 1374 break; | 1321 break; |
| 1375 } | 1322 } |
| 1376 case kInt32ArrayCid: | |
| 1377 case kUint32ArrayCid: | |
| 1378 case kTypedDataInt32ArrayCid: | 1323 case kTypedDataInt32ArrayCid: |
| 1379 case kTypedDataUint32ArrayCid: { | 1324 case kTypedDataUint32ArrayCid: { |
| 1380 Register value = locs()->in(2).reg(); | 1325 Register value = locs()->in(2).reg(); |
| 1381 __ SmiUntag(value); | 1326 __ SmiUntag(value); |
| 1382 __ movl(element_address, value); | 1327 __ movl(element_address, value); |
| 1383 break; | 1328 break; |
| 1384 } | 1329 } |
| 1385 case kFloat32ArrayCid: | |
| 1386 case kTypedDataFloat32ArrayCid: | 1330 case kTypedDataFloat32ArrayCid: |
| 1387 // Convert to single precision. | 1331 // Convert to single precision. |
| 1388 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); | 1332 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); |
| 1389 // Store. | 1333 // Store. |
| 1390 __ movss(element_address, locs()->temp(0).fpu_reg()); | 1334 __ movss(element_address, locs()->temp(0).fpu_reg()); |
| 1391 break; | 1335 break; |
| 1392 case kFloat64ArrayCid: | |
| 1393 case kTypedDataFloat64ArrayCid: | 1336 case kTypedDataFloat64ArrayCid: |
| 1394 __ movsd(element_address, locs()->in(2).fpu_reg()); | 1337 __ movsd(element_address, locs()->in(2).fpu_reg()); |
| 1395 break; | 1338 break; |
| 1396 default: | 1339 default: |
| 1397 UNREACHABLE(); | 1340 UNREACHABLE(); |
| 1398 } | 1341 } |
| 1399 } | 1342 } |
| 1400 | 1343 |
| 1401 | 1344 |
| 1402 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { | 1345 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { |
| (...skipping 1250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2653 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const { | 2596 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const { |
| 2654 // Calling convention on x64 uses XMM0 and XMM1 to pass the first two | 2597 // Calling convention on x64 uses XMM0 and XMM1 to pass the first two |
| 2655 // double arguments and XMM0 to return the result. Unfortunately | 2598 // double arguments and XMM0 to return the result. Unfortunately |
| 2656 // currently we can't specify these registers because ParallelMoveResolver | 2599 // currently we can't specify these registers because ParallelMoveResolver |
| 2657 // assumes that XMM0 is free at all times. | 2600 // assumes that XMM0 is free at all times. |
| 2658 // TODO(vegorov): allow XMM0 to be used. | 2601 // TODO(vegorov): allow XMM0 to be used. |
| 2659 ASSERT((InputCount() == 1) || (InputCount() == 2)); | 2602 ASSERT((InputCount() == 1) || (InputCount() == 2)); |
| 2660 const intptr_t kNumTemps = 0; | 2603 const intptr_t kNumTemps = 0; |
| 2661 LocationSummary* result = | 2604 LocationSummary* result = |
| 2662 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); | 2605 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); |
| 2663 result->set_in(0, Location::FpuRegisterLocation(XMM1, Location::kDouble)); | 2606 result->set_in(0, Location::FpuRegisterLocation(XMM1, kUnboxedDouble)); |
| 2664 if (InputCount() == 2) { | 2607 if (InputCount() == 2) { |
| 2665 result->set_in(1, Location::FpuRegisterLocation(XMM2, Location::kDouble)); | 2608 result->set_in(1, Location::FpuRegisterLocation(XMM2, kUnboxedDouble)); |
| 2666 } | 2609 } |
| 2667 result->set_out(Location::FpuRegisterLocation(XMM1, Location::kDouble)); | 2610 result->set_out(Location::FpuRegisterLocation(XMM1, kUnboxedDouble)); |
| 2668 return result; | 2611 return result; |
| 2669 } | 2612 } |
| 2670 | 2613 |
| 2671 | 2614 |
| 2672 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2615 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2673 ASSERT(locs()->in(0).fpu_reg() == XMM1); | 2616 ASSERT(locs()->in(0).fpu_reg() == XMM1); |
| 2674 __ EnterFrame(0); | 2617 __ EnterFrame(0); |
| 2675 __ ReserveAlignedFrameSpace(0); | 2618 __ ReserveAlignedFrameSpace(0); |
| 2676 __ movaps(XMM0, locs()->in(0).fpu_reg()); | 2619 __ movaps(XMM0, locs()->in(0).fpu_reg()); |
| 2677 if (InputCount() == 2) { | 2620 if (InputCount() == 2) { |
| (...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3225 PcDescriptors::kOther, | 3168 PcDescriptors::kOther, |
| 3226 locs()); | 3169 locs()); |
| 3227 __ Drop(2); // Discard type arguments and receiver. | 3170 __ Drop(2); // Discard type arguments and receiver. |
| 3228 } | 3171 } |
| 3229 | 3172 |
| 3230 } // namespace dart | 3173 } // namespace dart |
| 3231 | 3174 |
| 3232 #undef __ | 3175 #undef __ |
| 3233 | 3176 |
| 3234 #endif // defined TARGET_ARCH_X64 | 3177 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |