Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(242)

Side by Side Diff: runtime/vm/intermediate_language_x64.cc

Issue 12871010: Replace scalarlist optimizations and split external array loads into two IL instructions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/locations.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/locations.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698