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

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

Issue 11967012: Optimized loads/stores for scalar list: Uint8Clamped, Int8, Int16, Uint16. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 1006 matching lines...) Expand 10 before | Expand all | Expand 10 after
1017 } 1017 }
1018 1018
1019 1019
1020 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1020 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1021 Register array = locs()->in(0).reg(); 1021 Register array = locs()->in(0).reg();
1022 Location index = locs()->in(1); 1022 Location index = locs()->in(1);
1023 1023
1024 if (class_id() == kExternalUint8ArrayCid) { 1024 if (class_id() == kExternalUint8ArrayCid) {
1025 Register result = locs()->out().reg(); 1025 Register result = locs()->out().reg();
1026 Address element_address = index.IsRegister() 1026 Address element_address = index.IsRegister()
1027 ? Address(result, index.reg(), TIMES_1, 0) 1027 ? FlowGraphCompiler::ExternalElementAddressForRegIndex(
1028 : Address(result, Smi::Cast(index.constant()).Value()); 1028 class_id(), result, index.reg())
1029 : FlowGraphCompiler::ExternalElementAddressForIntIndex(
1030 class_id(), result, Smi::Cast(index.constant()).Value());
1029 if (index.IsRegister()) { 1031 if (index.IsRegister()) {
1030 __ SmiUntag(index.reg()); 1032 __ SmiUntag(index.reg());
1031 } 1033 }
1032 __ movq(result, 1034 __ movq(result,
1033 FieldAddress(array, ExternalUint8Array::external_data_offset())); 1035 FieldAddress(array, ExternalUint8Array::external_data_offset()));
1034 __ movq(result, 1036 __ movq(result,
1035 Address(result, ExternalByteArrayData<uint8_t>::data_offset())); 1037 Address(result, ExternalByteArrayData<uint8_t>::data_offset()));
1036 __ movzxb(result, element_address); 1038 __ movzxb(result, element_address);
1037 __ SmiTag(result); 1039 __ SmiTag(result);
1038 if (index.IsRegister()) { 1040 if (index.IsRegister()) {
(...skipping 16 matching lines...) Expand all
1055 // Promote to double. 1057 // Promote to double.
1056 __ cvtss2sd(result, locs()->out().xmm_reg()); 1058 __ cvtss2sd(result, locs()->out().xmm_reg());
1057 } else { 1059 } else {
1058 ASSERT(class_id() == kFloat64ArrayCid); 1060 ASSERT(class_id() == kFloat64ArrayCid);
1059 __ movsd(result, element_address); 1061 __ movsd(result, element_address);
1060 } 1062 }
1061 return; 1063 return;
1062 } 1064 }
1063 1065
1064 Register result = locs()->out().reg(); 1066 Register result = locs()->out().reg();
1065 if ((class_id() == kUint8ArrayCid) || 1067 switch (class_id()) {
1066 (class_id() == kUint8ClampedArrayCid)) { 1068 case kInt8ArrayCid:
1067 if (index.IsRegister()) { 1069 case kUint8ArrayCid:
1068 __ SmiUntag(index.reg()); 1070 case kUint8ClampedArrayCid:
1069 } 1071 if (index.IsRegister()) {
1070 __ movzxb(result, element_address); 1072 __ SmiUntag(index.reg());
1071 __ SmiTag(result); 1073 }
1072 if (index.IsRegister()) { 1074 if (class_id() == kInt8ArrayCid) {
1073 __ SmiTag(index.reg()); // Re-tag. 1075 __ movsxb(result, element_address);
1074 } 1076 } else {
1075 return; 1077 __ movzxb(result, element_address);
1078 }
1079 __ SmiTag(result);
1080 if (index.IsRegister()) {
1081 __ SmiTag(index.reg()); // Re-tag.
1082 }
1083 break;
1084 case kInt16ArrayCid:
1085 __ movsxw(result, element_address);
1086 __ SmiTag(result);
1087 break;
1088 case kUint16ArrayCid:
1089 __ movzxw(result, element_address);
1090 __ SmiTag(result);
1091 break;
1092 default:
1093 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
1094 __ movq(result, element_address);
1095 break;
1076 } 1096 }
1077
1078 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
1079 __ movq(result, element_address);
1080 } 1097 }
1081 1098
1082 1099
1083 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { 1100 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const {
1084 const intptr_t kNumInputs = 3; 1101 const intptr_t kNumInputs = 3;
1085 const intptr_t numTemps = 0; 1102 const intptr_t kNumTemps = 0;
1086 LocationSummary* locs = 1103 LocationSummary* locs =
1087 new LocationSummary(kNumInputs, numTemps, LocationSummary::kNoCall); 1104 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1088 locs->set_in(0, Location::RequiresRegister()); 1105 locs->set_in(0, Location::RequiresRegister());
1089 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) 1106 locs->set_in(1, CanBeImmediateIndex(index(), class_id())
1090 ? Location::RegisterOrSmiConstant(index()) 1107 ? Location::RegisterOrSmiConstant(index())
1091 : Location::RequiresRegister()); 1108 : Location::RequiresRegister());
1092 switch (class_id()) { 1109 switch (class_id()) {
1093 case kArrayCid: 1110 case kArrayCid:
1094 locs->set_in(2, ShouldEmitStoreBarrier() 1111 locs->set_in(2, ShouldEmitStoreBarrier()
1095 ? Location::WritableRegister() 1112 ? Location::WritableRegister()
1096 : Location::RegisterOrConstant(value())); 1113 : Location::RegisterOrConstant(value()));
1097 break; 1114 break;
1115 case kInt8ArrayCid:
1098 case kUint8ArrayCid: 1116 case kUint8ArrayCid:
1117 case kUint8ClampedArrayCid:
1099 // TODO(fschneider): Add location constraint for byte registers (RAX, 1118 // TODO(fschneider): Add location constraint for byte registers (RAX,
1100 // RBX, RCX, RDX) instead of using a fixed register. 1119 // RBX, RCX, RDX) instead of using a fixed register.
1101 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), RAX)); 1120 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), RAX));
1102 break; 1121 break;
1122 case kInt16ArrayCid:
1123 case kUint16ArrayCid:
1124 // TODO(fschneider): Support int16/uint16 constants.
1125 locs->set_in(2, Location::WritableRegister());
1126 break;
1103 case kFloat32ArrayCid: 1127 case kFloat32ArrayCid:
1104 // Need temp register for float-to-double conversion. 1128 // Need temp register for float-to-double conversion.
1105 locs->AddTemp(Location::RequiresXmmRegister()); 1129 locs->AddTemp(Location::RequiresXmmRegister());
1106 // Fall through. 1130 // Fall through.
1107 case kFloat64ArrayCid: 1131 case kFloat64ArrayCid:
1108 // TODO(srdjan): Support Float64 constants. 1132 // TODO(srdjan): Support Float64 constants.
1109 locs->set_in(2, Location::RequiresXmmRegister()); 1133 locs->set_in(2, Location::RequiresXmmRegister());
1110 break; 1134 break;
1111 default: 1135 default:
1112 UNREACHABLE(); 1136 UNREACHABLE();
(...skipping 19 matching lines...) Expand all
1132 Register value = locs()->in(2).reg(); 1156 Register value = locs()->in(2).reg();
1133 __ StoreIntoObject(array, element_address, value); 1157 __ StoreIntoObject(array, element_address, value);
1134 } else if (locs()->in(2).IsConstant()) { 1158 } else if (locs()->in(2).IsConstant()) {
1135 const Object& constant = locs()->in(2).constant(); 1159 const Object& constant = locs()->in(2).constant();
1136 __ StoreObject(element_address, constant); 1160 __ StoreObject(element_address, constant);
1137 } else { 1161 } else {
1138 Register value = locs()->in(2).reg(); 1162 Register value = locs()->in(2).reg();
1139 __ StoreIntoObjectNoBarrier(array, element_address, value); 1163 __ StoreIntoObjectNoBarrier(array, element_address, value);
1140 } 1164 }
1141 break; 1165 break;
1166 case kInt8ArrayCid:
1142 case kUint8ArrayCid: 1167 case kUint8ArrayCid:
1143 if (index.IsRegister()) { 1168 if (index.IsRegister()) {
1144 __ SmiUntag(index.reg()); 1169 __ SmiUntag(index.reg());
1145 } 1170 }
1146 if (locs()->in(2).IsConstant()) { 1171 if (locs()->in(2).IsConstant()) {
1147 const Smi& constant = Smi::Cast(locs()->in(2).constant()); 1172 const Smi& constant = Smi::Cast(locs()->in(2).constant());
1148 __ movb(element_address, 1173 __ movb(element_address,
1149 Immediate(static_cast<int8_t>(constant.Value()))); 1174 Immediate(static_cast<int8_t>(constant.Value())));
1150 } else { 1175 } else {
1151 ASSERT(locs()->in(2).reg() == RAX); 1176 ASSERT(locs()->in(2).reg() == RAX);
1152 __ SmiUntag(RAX); 1177 __ SmiUntag(RAX);
1153 __ movb(element_address, RAX); 1178 __ movb(element_address, RAX);
1154 } 1179 }
1155 if (index.IsRegister()) { 1180 if (index.IsRegister()) {
1156 __ SmiTag(index.reg()); // Re-tag. 1181 __ SmiTag(index.reg()); // Re-tag.
1157 } 1182 }
1158 break; 1183 break;
1184 case kUint8ClampedArrayCid: {
1185 if (index.IsRegister()) {
1186 __ SmiUntag(index.reg());
1187 }
1188 if (locs()->in(2).IsConstant()) {
1189 const Smi& constant = Smi::Cast(locs()->in(2).constant());
1190 intptr_t value = constant.Value();
1191 // Clamp to 0x0 or 0xFF respectively.
1192 if (value > 0xFF) {
1193 value = 0xFF;
1194 } else if (value < 0) {
1195 value = 0;
1196 }
1197 __ movb(element_address,
1198 Immediate(static_cast<int8_t>(value)));
1199 } else {
1200 ASSERT(locs()->in(2).reg() == RAX);
1201 Label store_value, store_0xff;
1202 __ SmiUntag(RAX);
1203 __ cmpq(RAX, Immediate(0xFF));
1204 __ j(BELOW_EQUAL, &store_value, Assembler::kNearJump);
1205 // Clamp to 0x0 or 0xFF respectively.
1206 __ j(GREATER, &store_0xff);
1207 __ xorq(RAX, RAX);
1208 __ jmp(&store_value, Assembler::kNearJump);
1209 __ Bind(&store_0xff);
1210 __ movq(RAX, Immediate(0xFF));
1211 __ Bind(&store_value);
1212 __ movb(element_address, RAX);
1213 }
1214 if (index.IsRegister()) {
1215 __ SmiTag(index.reg()); // Re-tag.
1216 }
1217 break;
1218 }
1219 case kInt16ArrayCid:
1220 case kUint16ArrayCid: {
1221 Register value = locs()->in(2).reg();
1222 __ SmiUntag(value);
1223 __ movw(element_address, value);
1224 break;
1225 }
1159 case kFloat32ArrayCid: 1226 case kFloat32ArrayCid:
1160 // Convert to single precision. 1227 // Convert to single precision.
1161 __ cvtsd2ss(locs()->temp(0).xmm_reg(), locs()->in(2).xmm_reg()); 1228 __ cvtsd2ss(locs()->temp(0).xmm_reg(), locs()->in(2).xmm_reg());
1162 // Store. 1229 // Store.
1163 __ movss(element_address, locs()->temp(0).xmm_reg()); 1230 __ movss(element_address, locs()->temp(0).xmm_reg());
1164 break; 1231 break;
1165 case kFloat64ArrayCid: 1232 case kFloat64ArrayCid:
1166 __ movsd(element_address, locs()->in(2).xmm_reg()); 1233 __ movsd(element_address, locs()->in(2).xmm_reg());
1167 break; 1234 break;
1168 default: 1235 default:
(...skipping 1335 matching lines...) Expand 10 before | Expand all | Expand 10 after
2504 2571
2505 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2572 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2506 UNIMPLEMENTED(); 2573 UNIMPLEMENTED();
2507 } 2574 }
2508 2575
2509 } // namespace dart 2576 } // namespace dart
2510 2577
2511 #undef __ 2578 #undef __
2512 2579
2513 #endif // defined TARGET_ARCH_X64 2580 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698