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

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

Issue 552303005: Fix StoreIndexedInstr input representation requirements for Int32/Uint32 arrays. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix typo Created 6 years, 3 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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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_ARM64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64.
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
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 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 if (!locs()->out(0).IsInvalid()) { 281 if (!locs()->out(0).IsInvalid()) {
282 const Register result = locs()->out(0).reg(); 282 const Register result = locs()->out(0).reg();
283 __ LoadObject(result, value(), PP); 283 __ LoadObject(result, value(), PP);
284 } 284 }
285 } 285 }
286 286
287 287
288 LocationSummary* UnboxedConstantInstr::MakeLocationSummary(Isolate* isolate, 288 LocationSummary* UnboxedConstantInstr::MakeLocationSummary(Isolate* isolate,
289 bool opt) const { 289 bool opt) const {
290 const intptr_t kNumInputs = 0; 290 const intptr_t kNumInputs = 0;
291 const Location out = (representation_ == kUnboxedInt32) ?
292 Location::RequiresRegister() : Location::RequiresFpuRegister();
291 return LocationSummary::Make(isolate, 293 return LocationSummary::Make(isolate,
292 kNumInputs, 294 kNumInputs,
293 Location::RequiresFpuRegister(), 295 out,
294 LocationSummary::kNoCall); 296 LocationSummary::kNoCall);
295 } 297 }
296 298
297 299
298 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 300 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
299 ASSERT(representation_ == kUnboxedDouble);
300 if (!locs()->out(0).IsInvalid()) { 301 if (!locs()->out(0).IsInvalid()) {
301 if (Utils::DoublesBitEqual(Double::Cast(value()).value(), 0.0)) { 302 switch (representation_) {
302 const VRegister dst = locs()->out(0).fpu_reg(); 303 case kUnboxedDouble:
303 __ veor(dst, dst, dst); 304 if (Utils::DoublesBitEqual(Double::Cast(value()).value(), 0.0)) {
304 } else { 305 const VRegister dst = locs()->out(0).fpu_reg();
305 const VRegister dst = locs()->out(0).fpu_reg(); 306 __ veor(dst, dst, dst);
306 __ LoadDImmediate(dst, Double::Cast(value()).value(), PP); 307 } else {
308 const VRegister dst = locs()->out(0).fpu_reg();
309 __ LoadDImmediate(dst, Double::Cast(value()).value(), PP);
310 }
311 break;
312 case kUnboxedInt32:
313 __ LoadImmediate(locs()->out(0).reg(),
314 static_cast<int32_t>(Smi::Cast(value()).Value()),
315 PP);
316 break;
317 default:
318 UNREACHABLE();
319 break;
307 } 320 }
308 } 321 }
309 } 322 }
310 323
311 324
312 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Isolate* isolate, 325 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Isolate* isolate,
313 bool opt) const { 326 bool opt) const {
314 const intptr_t kNumInputs = 3; 327 const intptr_t kNumInputs = 3;
315 const intptr_t kNumTemps = 0; 328 const intptr_t kNumTemps = 0;
316 LocationSummary* summary = new(isolate) LocationSummary( 329 LocationSummary* summary = new(isolate) LocationSummary(
(...skipping 806 matching lines...) Expand 10 before | Expand all | Expand 10 after
1123 switch (class_id_) { 1136 switch (class_id_) {
1124 case kArrayCid: 1137 case kArrayCid:
1125 case kOneByteStringCid: 1138 case kOneByteStringCid:
1126 case kTypedDataInt8ArrayCid: 1139 case kTypedDataInt8ArrayCid:
1127 case kTypedDataUint8ArrayCid: 1140 case kTypedDataUint8ArrayCid:
1128 case kExternalTypedDataUint8ArrayCid: 1141 case kExternalTypedDataUint8ArrayCid:
1129 case kTypedDataUint8ClampedArrayCid: 1142 case kTypedDataUint8ClampedArrayCid:
1130 case kExternalTypedDataUint8ClampedArrayCid: 1143 case kExternalTypedDataUint8ClampedArrayCid:
1131 case kTypedDataInt16ArrayCid: 1144 case kTypedDataInt16ArrayCid:
1132 case kTypedDataUint16ArrayCid: 1145 case kTypedDataUint16ArrayCid:
1146 return kTagged;
1133 case kTypedDataInt32ArrayCid: 1147 case kTypedDataInt32ArrayCid:
1148 return kUnboxedInt32;
1134 case kTypedDataUint32ArrayCid: 1149 case kTypedDataUint32ArrayCid:
1135 return kTagged; 1150 return kUnboxedUint32;
1136 case kTypedDataFloat32ArrayCid: 1151 case kTypedDataFloat32ArrayCid:
1137 case kTypedDataFloat64ArrayCid: 1152 case kTypedDataFloat64ArrayCid:
1138 return kUnboxedDouble; 1153 return kUnboxedDouble;
1139 case kTypedDataFloat32x4ArrayCid: 1154 case kTypedDataFloat32x4ArrayCid:
1140 return kUnboxedFloat32x4; 1155 return kUnboxedFloat32x4;
1141 case kTypedDataInt32x4ArrayCid: 1156 case kTypedDataInt32x4ArrayCid:
1142 return kUnboxedInt32x4; 1157 return kUnboxedInt32x4;
1143 case kTypedDataFloat64x2ArrayCid: 1158 case kTypedDataFloat64x2ArrayCid:
1144 return kUnboxedFloat64x2; 1159 return kUnboxedFloat64x2;
1145 default: 1160 default:
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1264 case kTypedDataInt16ArrayCid: 1279 case kTypedDataInt16ArrayCid:
1265 case kTypedDataUint16ArrayCid: { 1280 case kTypedDataUint16ArrayCid: {
1266 const Register value = locs()->in(2).reg(); 1281 const Register value = locs()->in(2).reg();
1267 __ SmiUntag(TMP, value); 1282 __ SmiUntag(TMP, value);
1268 __ str(TMP, element_address, kUnsignedHalfword); 1283 __ str(TMP, element_address, kUnsignedHalfword);
1269 break; 1284 break;
1270 } 1285 }
1271 case kTypedDataInt32ArrayCid: 1286 case kTypedDataInt32ArrayCid:
1272 case kTypedDataUint32ArrayCid: { 1287 case kTypedDataUint32ArrayCid: {
1273 const Register value = locs()->in(2).reg(); 1288 const Register value = locs()->in(2).reg();
1274 __ SmiUntag(TMP, value); 1289 __ str(value, element_address, kUnsignedWord);
1275 __ str(TMP, element_address, kUnsignedWord);
1276 break; 1290 break;
1277 } 1291 }
1278 case kTypedDataFloat32ArrayCid: { 1292 case kTypedDataFloat32ArrayCid: {
1279 const VRegister value_reg = locs()->in(2).fpu_reg(); 1293 const VRegister value_reg = locs()->in(2).fpu_reg();
1280 __ fstrs(value_reg, element_address); 1294 __ fstrs(value_reg, element_address);
1281 break; 1295 break;
1282 } 1296 }
1283 case kTypedDataFloat64ArrayCid: { 1297 case kTypedDataFloat64ArrayCid: {
1284 const VRegister value_reg = locs()->in(2).fpu_reg(); 1298 const VRegister value_reg = locs()->in(2).fpu_reg();
1285 __ fstrd(value_reg, element_address); 1299 __ fstrd(value_reg, element_address);
(...skipping 3864 matching lines...) Expand 10 before | Expand all | Expand 10 after
5150 5164
5151 5165
5152 CompileType UnaryUint32OpInstr::ComputeType() const { 5166 CompileType UnaryUint32OpInstr::ComputeType() const {
5153 return CompileType::FromCid(kSmiCid); 5167 return CompileType::FromCid(kSmiCid);
5154 } 5168 }
5155 5169
5156 5170
5157 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryUint32OpInstr) 5171 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryUint32OpInstr)
5158 DEFINE_UNIMPLEMENTED_INSTRUCTION(ShiftUint32OpInstr) 5172 DEFINE_UNIMPLEMENTED_INSTRUCTION(ShiftUint32OpInstr)
5159 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnaryUint32OpInstr) 5173 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnaryUint32OpInstr)
5160 DEFINE_UNIMPLEMENTED_INSTRUCTION(BoxInt32Instr)
5161 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnboxInt32Instr)
5162 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr) 5174 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr)
5163 DEFINE_UNIMPLEMENTED_INSTRUCTION(BoxUint32Instr)
5164 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnboxedIntConverterInstr)
5165 5175
5166 5176
5167 LocationSummary* UnboxUint32Instr::MakeLocationSummary(Isolate* isolate, 5177 LocationSummary* UnboxIntNInstr::MakeLocationSummary(Isolate* isolate,
5168 bool opt) const { 5178 bool opt) const {
5169 const intptr_t kNumInputs = 1; 5179 const intptr_t kNumInputs = 1;
5170 const intptr_t kNumTemps = 0; 5180 const intptr_t kNumTemps = 0;
5171 LocationSummary* summary = new(isolate) LocationSummary( 5181 LocationSummary* summary = new(isolate) LocationSummary(
5172 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5182 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5173 summary->set_in(0, Location::RequiresRegister()); 5183 summary->set_in(0, Location::RequiresRegister());
5174 summary->set_out(0, Location::SameAsFirstInput()); 5184 summary->set_out(0, Location::RequiresRegister());
5175 return summary; 5185 return summary;
5176 } 5186 }
5177 5187
5178 5188
5179 void UnboxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 5189 void UnboxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5180 const intptr_t value_cid = value()->Type()->ToCid(); 5190 const intptr_t value_cid = value()->Type()->ToCid();
5191 const Register out = locs()->out(0).reg();
5181 const Register value = locs()->in(0).reg(); 5192 const Register value = locs()->in(0).reg();
5182 ASSERT(value == locs()->out(0).reg()); 5193 Label* deopt = CanDeoptimize() ?
5194 compiler->AddDeoptStub(deopt_id_, ICData::kDeoptUnboxInteger) : NULL;
5183 5195
5184 if (value_cid == kSmiCid) { 5196 if (value_cid == kSmiCid) {
5185 __ SmiUntag(value); 5197 __ SmiUntag(out, value);
5198 } else if (value_cid == kMintCid) {
5199 __ LoadFieldFromOffset(out, value, Mint::value_offset(), PP);
5186 } else { 5200 } else {
5187 Label* deopt = compiler->AddDeoptStub(deopt_id_, 5201 Label done;
5188 ICData::kDeoptUnboxInteger); 5202 __ SmiUntag(out, value);
5189 __ tsti(value, kSmiTagMask); 5203 __ TestImmediate(value, kSmiTagMask, PP);
5204 __ b(&done, EQ);
5205 __ CompareClassId(value, kMintCid, PP);
5190 __ b(deopt, NE); 5206 __ b(deopt, NE);
5191 __ SmiUntag(value); 5207 __ LoadFieldFromOffset(out, value, Mint::value_offset(), PP);
5208 __ Bind(&done);
5209 }
5210
5211 // TODO(vegorov): as it is implemented right now truncating unboxing would
5212 // leave "garbage" in the higher word.
5213 if (!is_truncating() && (deopt != NULL)) {
5214 ASSERT(representation() == kUnboxedInt32);
5215 __ cmp(out, Operand(out, SXTW, 0));
5216 __ b(deopt, NE);
5192 } 5217 }
5193 } 5218 }
5194 5219
5220
5221 LocationSummary* BoxIntNInstr::MakeLocationSummary(Isolate* isolate,
5222 bool opt) const {
5223 ASSERT((from_representation() == kUnboxedInt32) ||
5224 (from_representation() == kUnboxedUint32));
5225 const intptr_t kNumInputs = 1;
5226 const intptr_t kNumTemps = 0;
5227 LocationSummary* summary = new(isolate) LocationSummary(
5228 isolate,
5229 kNumInputs,
5230 kNumTemps,
5231 LocationSummary::kNoCall);
5232 summary->set_in(0, Location::RequiresRegister());
5233 summary->set_out(0, Location::RequiresRegister());
5234 return summary;
5235 }
5236
5237
5238 void BoxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5239 Register value = locs()->in(0).reg();
5240 Register out = locs()->out(0).reg();
5241 ASSERT(value != out);
5242
5243 ASSERT(kSmiTagSize == 1);
5244 // TODO(vegorov) implement and use UBFM/SBFM for this.
5245 __ Lsl(out, value, 32);
5246 if (from_representation() == kUnboxedInt32) {
5247 __ Asr(out, out, 32 - kSmiTagSize);
5248 } else {
5249 ASSERT(from_representation() == kUnboxedUint32);
5250 __ Lsr(out, out, 32 - kSmiTagSize);
5251 }
5252 }
5253
5254
5255 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate,
5256 bool opt) const {
5257 const intptr_t kNumInputs = 1;
5258 const intptr_t kNumTemps = 0;
5259 LocationSummary* summary = new(isolate) LocationSummary(
5260 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5261 if (from() == kUnboxedMint) {
5262 UNREACHABLE();
5263 } else if (to() == kUnboxedMint) {
5264 UNREACHABLE();
5265 } else {
5266 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32));
5267 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32));
5268 summary->set_in(0, Location::RequiresRegister());
5269 summary->set_out(0, Location::RequiresRegister());
5270 }
5271 return summary;
5272 }
5273
5274
5275 void UnboxedIntConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5276 if (from() == kUnboxedInt32 && to() == kUnboxedUint32) {
5277 const Register value = locs()->in(0).reg();
5278 const Register out = locs()->out(0).reg();
5279 // Representations are bitwise equivalent but we want to normalize
5280 // upperbits for safety reasons.
5281 // TODO(vegorov) if we ensure that we never use kDoubleWord size
5282 // with it then we could avoid this.
5283 // TODO(vegorov) implement and use UBFM for zero extension.
5284 __ Lsl(out, value, 32);
5285 __ Lsr(out, out, 32);
5286 } else if (from() == kUnboxedUint32 && to() == kUnboxedInt32) {
5287 // Representations are bitwise equivalent.
5288 // TODO(vegorov) if we ensure that we never use kDoubleWord size
5289 // with it then we could avoid this.
5290 // TODO(vegorov) implement and use SBFM for sign extension.
5291 const Register value = locs()->in(0).reg();
5292 const Register out = locs()->out(0).reg();
5293 __ Lsl(out, value, 32);
5294 __ Asr(out, out, 32);
5295 if (CanDeoptimize()) {
5296 Label* deopt =
5297 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger);
5298 __ cmp(out, Operand(value, UXTW, 0));
5299 __ b(deopt, NE);
5300 }
5301 } else if (from() == kUnboxedMint) {
5302 UNREACHABLE();
5303 } else if (to() == kUnboxedMint) {
5304 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32));
5305 UNREACHABLE();
5306 } else {
5307 UNREACHABLE();
5308 }
5309 }
5310
5195 5311
5196 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, 5312 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate,
5197 bool opt) const { 5313 bool opt) const {
5198 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); 5314 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall);
5199 } 5315 }
5200 5316
5201 5317
5202 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5318 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5203 compiler->GenerateRuntimeCall(token_pos(), 5319 compiler->GenerateRuntimeCall(token_pos(),
5204 deopt_id(), 5320 deopt_id(),
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
5427 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); 5543 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs());
5428 #if defined(DEBUG) 5544 #if defined(DEBUG)
5429 __ LoadImmediate(R4, kInvalidObjectPointer, kNoPP); 5545 __ LoadImmediate(R4, kInvalidObjectPointer, kNoPP);
5430 __ LoadImmediate(R5, kInvalidObjectPointer, kNoPP); 5546 __ LoadImmediate(R5, kInvalidObjectPointer, kNoPP);
5431 #endif 5547 #endif
5432 } 5548 }
5433 5549
5434 } // namespace dart 5550 } // namespace dart
5435 5551
5436 #endif // defined TARGET_ARCH_ARM64 5552 #endif // defined TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698