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

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

Issue 345563007: Add Uint32 representation (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 5 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.cc ('k') | runtime/vm/intermediate_language_arm64.cc » ('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_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 5949 matching lines...) Expand 10 before | Expand all | Expand 10 after
5960 if (!is_smi()) { 5960 if (!is_smi()) {
5961 summary->set_temp(0, Location::RequiresRegister()); 5961 summary->set_temp(0, Location::RequiresRegister());
5962 } 5962 }
5963 summary->set_out(0, Location::RequiresRegister()); 5963 summary->set_out(0, Location::RequiresRegister());
5964 return summary; 5964 return summary;
5965 } 5965 }
5966 5966
5967 5967
5968 class BoxIntegerSlowPath : public SlowPathCode { 5968 class BoxIntegerSlowPath : public SlowPathCode {
5969 public: 5969 public:
5970 explicit BoxIntegerSlowPath(BoxIntegerInstr* instruction) 5970 explicit BoxIntegerSlowPath(Definition* instruction)
5971 : instruction_(instruction) { } 5971 : instruction_(instruction) { }
5972 5972
5973 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 5973 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
5974 __ Comment("BoxIntegerSlowPath"); 5974 __ Comment("BoxIntegerSlowPath");
5975 __ Bind(entry_label()); 5975 __ Bind(entry_label());
5976 Isolate* isolate = compiler->isolate(); 5976 Isolate* isolate = compiler->isolate();
5977 StubCode* stub_code = isolate->stub_code(); 5977 StubCode* stub_code = isolate->stub_code();
5978 const Class& mint_class = 5978 const Class& mint_class =
5979 Class::ZoneHandle(isolate->object_store()->mint_class()); 5979 Class::ZoneHandle(isolate->object_store()->mint_class());
5980 const Code& stub = 5980 const Code& stub =
5981 Code::Handle(isolate, stub_code->GetAllocationStubForClass(mint_class)); 5981 Code::Handle(isolate, stub_code->GetAllocationStubForClass(mint_class));
5982 const ExternalLabel label(stub.EntryPoint()); 5982 const ExternalLabel label(stub.EntryPoint());
5983 5983
5984 LocationSummary* locs = instruction_->locs(); 5984 LocationSummary* locs = instruction_->locs();
5985 ASSERT(!locs->live_registers()->Contains(locs->out(0))); 5985 ASSERT(!locs->live_registers()->Contains(locs->out(0)));
5986 5986
5987 compiler->SaveLiveRegisters(locs); 5987 compiler->SaveLiveRegisters(locs);
5988 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 5988 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
5989 &label, 5989 &label,
5990 RawPcDescriptors::kOther, 5990 RawPcDescriptors::kOther,
5991 locs); 5991 locs);
5992 __ mov(locs->out(0).reg(), Operand(R0)); 5992 __ mov(locs->out(0).reg(), Operand(R0));
5993 compiler->RestoreLiveRegisters(locs); 5993 compiler->RestoreLiveRegisters(locs);
5994 5994
5995 __ b(exit_label()); 5995 __ b(exit_label());
5996 } 5996 }
5997 5997
5998 private: 5998 private:
5999 BoxIntegerInstr* instruction_; 5999 Definition* instruction_;
6000 }; 6000 };
6001 6001
6002 6002
6003 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6003 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6004 if (is_smi()) { 6004 if (is_smi()) {
6005 PairLocation* value_pair = locs()->in(0).AsPairLocation(); 6005 PairLocation* value_pair = locs()->in(0).AsPairLocation();
6006 Register value_lo = value_pair->At(0).reg(); 6006 Register value_lo = value_pair->At(0).reg();
6007 Register out_reg = locs()->out(0).reg(); 6007 Register out_reg = locs()->out(0).reg();
6008 __ mov(out_reg, Operand(value_lo)); 6008 __ mov(out_reg, Operand(value_lo));
6009 __ SmiTag(out_reg); 6009 __ SmiTag(out_reg);
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
6266 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryMintOp); 6266 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryMintOp);
6267 } 6267 }
6268 __ mvn(out_lo, Operand(left_lo)); 6268 __ mvn(out_lo, Operand(left_lo));
6269 __ mvn(out_hi, Operand(left_hi)); 6269 __ mvn(out_hi, Operand(left_hi));
6270 if (FLAG_throw_on_javascript_int_overflow) { 6270 if (FLAG_throw_on_javascript_int_overflow) {
6271 EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi); 6271 EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi);
6272 } 6272 }
6273 } 6273 }
6274 6274
6275 6275
6276 CompileType BinaryUint32OpInstr::ComputeType() const {
6277 return CompileType::Int();
6278 }
6279
6280
6281 CompileType ShiftUint32OpInstr::ComputeType() const {
6282 return CompileType::Int();
6283 }
6284
6285
6286 CompileType UnaryUint32OpInstr::ComputeType() const {
6287 return CompileType::Int();
6288 }
6289
6290
6291 CompileType BoxUint32Instr::ComputeType() const {
6292 return CompileType::Int();
6293 }
6294
6295
6296 CompileType UnboxUint32Instr::ComputeType() const {
6297 return CompileType::Int();
6298 }
6299
6300
6301 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6302 bool opt) const {
6303 const intptr_t kNumInputs = 2;
6304 const intptr_t kNumTemps = 0;
6305 LocationSummary* summary = new(isolate) LocationSummary(
6306 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6307 summary->set_in(0, Location::RequiresRegister());
6308 summary->set_in(1, Location::RequiresRegister());
6309 summary->set_out(0, Location::RequiresRegister());
6310 return summary;
6311 }
6312
6313
6314 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6315 Register left = locs()->in(0).reg();
6316 Register right = locs()->in(1).reg();
6317 Register out = locs()->out(0).reg();
6318 ASSERT(out != left);
6319 switch (op_kind()) {
6320 case Token::kBIT_AND:
6321 __ and_(out, left, Operand(right));
6322 break;
6323 case Token::kBIT_OR:
6324 __ orr(out, left, Operand(right));
6325 break;
6326 case Token::kBIT_XOR:
6327 __ eor(out, left, Operand(right));
6328 break;
6329 case Token::kADD:
6330 __ add(out, left, Operand(right));
6331 break;
6332 case Token::kSUB:
6333 __ sub(out, left, Operand(right));
6334 break;
6335 default:
6336 UNREACHABLE();
6337 }
6338 }
6339
6340
6341 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6342 bool opt) const {
6343 const intptr_t kNumInputs = 2;
6344 const intptr_t kNumTemps = 1;
6345 LocationSummary* summary = new(isolate) LocationSummary(
6346 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6347 summary->set_in(0, Location::RequiresRegister());
6348 summary->set_in(1, Location::RegisterOrSmiConstant(right()));
6349 summary->set_temp(0, Location::RequiresRegister());
6350 summary->set_out(0, Location::RequiresRegister());
6351 return summary;
6352 }
6353
6354
6355 void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6356 const intptr_t kShifterLimit = 31;
6357
6358 Register left = locs()->in(0).reg();
6359 Register out = locs()->out(0).reg();
6360 Register temp = locs()->temp(0).reg();
6361
6362 ASSERT(left != out);
6363
6364 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
6365
6366 if (locs()->in(1).IsConstant()) {
6367 // Shifter is constant.
6368
6369 const Object& constant = locs()->in(1).constant();
6370 ASSERT(constant.IsSmi());
6371 const intptr_t shift_value = Smi::Cast(constant).Value();
6372
6373 // Check constant shift value.
6374 if (shift_value == 0) {
6375 // Nothing to do.
6376 __ mov(out, Operand(left));
6377 } else if (shift_value < 0) {
6378 // Invalid shift value.
6379 __ b(deopt);
6380 } else if (shift_value > kShifterLimit) {
6381 // Result is 0.
6382 __ eor(out, out, Operand(out));
6383 } else {
6384 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit).
6385 switch (op_kind()) {
6386 case Token::kSHR:
6387 __ Lsr(out, left, shift_value);
6388 break;
6389 case Token::kSHL:
6390 __ Lsl(out, left, shift_value);
6391 break;
6392 default:
6393 UNREACHABLE();
6394 }
6395 }
6396 return;
6397 }
6398
6399 // Non constant shift value.
6400
6401 Register shifter = locs()->in(1).reg();
6402
6403 __ mov(temp, Operand(shifter));
6404 __ SmiUntag(temp);
6405 __ CompareImmediate(temp, 0);
6406 // If shift value is < 0, deoptimize.
6407 __ b(deopt, LT);
6408 __ CompareImmediate(temp, kShifterLimit);
6409 // > kShifterLimit, result is 0.
6410 __ eor(out, out, Operand(out), HI);
6411 // Do the shift.
6412 switch (op_kind()) {
6413 case Token::kSHR:
6414 __ Lsr(out, left, temp, LS);
6415 break;
6416 case Token::kSHL:
6417 __ Lsl(out, left, temp, LS);
6418 break;
6419 default:
6420 UNREACHABLE();
6421 }
6422 }
6423
6424
6425 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6426 bool opt) const {
6427 const intptr_t kNumInputs = 1;
6428 const intptr_t kNumTemps = 0;
6429 LocationSummary* summary = new(isolate) LocationSummary(
6430 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6431 summary->set_in(0, Location::RequiresRegister());
6432 summary->set_out(0, Location::RequiresRegister());
6433 return summary;
6434 }
6435
6436
6437 void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6438 Register left = locs()->in(0).reg();
6439 Register out = locs()->out(0).reg();
6440 ASSERT(left != out);
6441
6442 ASSERT(op_kind() == Token::kBIT_NOT);
6443
6444 __ mvn(out, Operand(left));
6445 }
6446
6447
6448 LocationSummary* BoxUint32Instr::MakeLocationSummary(Isolate* isolate,
6449 bool opt) const {
6450 const intptr_t kNumInputs = 1;
6451 const intptr_t kNumTemps = 1;
6452 LocationSummary* summary = new(isolate) LocationSummary(
6453 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
6454 summary->set_in(0, Location::RequiresRegister());
6455 summary->set_temp(0, Location::RequiresRegister());
6456 summary->set_out(0, Location::RequiresRegister());
6457 return summary;
6458 }
6459
6460
6461 void BoxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
6462 BoxIntegerSlowPath* slow_path = new BoxIntegerSlowPath(this);
6463 compiler->AddSlowPathCode(slow_path);
6464 Register value = locs()->in(0).reg();
6465 Register out = locs()->out(0).reg();
6466 Register temp = locs()->temp(0).reg();
6467 ASSERT(value != out);
6468
6469 Label not_smi, done;
6470
6471 // TODO(johnmccutchan): Use range information to fast path smi / mint boxing.
6472
6473 // Test if this value is <= kSmiMax.
6474 __ CompareImmediate(value, kSmiMax);
6475 __ b(&not_smi, HI);
6476 // Smi.
6477 __ mov(out, Operand(value));
6478 __ SmiTag(out);
6479 __ b(&done);
6480 __ Bind(&not_smi);
6481 // Allocate a mint.
6482 __ TryAllocate(
6483 Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()),
6484 slow_path->entry_label(),
6485 out,
6486 temp);
6487 __ Bind(slow_path->exit_label());
6488 // Copy low word into mint.
6489 __ StoreToOffset(kWord,
6490 value,
6491 out,
6492 Mint::value_offset() - kHeapObjectTag);
6493 // Zero high word.
6494 __ eor(temp, temp, Operand(temp));
6495 __ StoreToOffset(kWord,
6496 temp,
6497 out,
6498 Mint::value_offset() - kHeapObjectTag + kWordSize);
6499 __ Bind(&done);
6500 }
6501
6502
6503
6504 LocationSummary* UnboxUint32Instr::MakeLocationSummary(Isolate* isolate,
6505 bool opt) const {
6506 const intptr_t value_cid = value()->Type()->ToCid();
6507 const intptr_t kNumInputs = 1;
6508 const intptr_t kNumTemps =
6509 ((value_cid == kMintCid) || (value_cid == kSmiCid)) ? 0 : 1;
6510 LocationSummary* summary = new(isolate) LocationSummary(
6511 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6512 summary->set_in(0, Location::RequiresRegister());
6513 if (kNumTemps > 0) {
6514 summary->set_temp(0, Location::RequiresRegister());
6515 }
6516 summary->set_out(0, Location::RequiresRegister());
6517 return summary;
6518 }
6519
6520
6521 void UnboxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
6522 const intptr_t value_cid = value()->Type()->ToCid();
6523 const Register value = locs()->in(0).reg();
6524 const Register out = locs()->out(0).reg();
6525 ASSERT(value != out);
6526
6527 // TODO(johnmccutchan): Emit better code for constant inputs.
6528 if (value_cid == kMintCid) {
6529 __ LoadFromOffset(kWord, out, value, Mint::value_offset() - kHeapObjectTag);
6530 } else if (value_cid == kSmiCid) {
6531 __ mov(out, Operand(value));
6532 __ SmiUntag(out);
6533 } else {
6534 Register temp = locs()->temp(0).reg();
6535 Label* deopt = compiler->AddDeoptStub(deopt_id_,
6536 ICData::kDeoptUnboxInteger);
6537 Label done;
6538 __ tst(value, Operand(kSmiTagMask));
6539 // Smi case.
6540 __ mov(out, Operand(value), EQ);
6541 __ SmiUntag(out, EQ);
6542 __ b(&done, EQ);
6543 // Mint case.
6544 __ CompareClassId(value, kMintCid, temp);
6545 __ b(deopt, NE);
6546 __ LoadFromOffset(kWord, out, value, Mint::value_offset() - kHeapObjectTag);
6547 __ Bind(&done);
6548 }
6549 }
6550
6551
6552 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate,
6553 bool opt) const {
6554 const intptr_t kNumInputs = 1;
6555 const intptr_t kNumTemps = 0;
6556 LocationSummary* summary = new(isolate) LocationSummary(
6557 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6558 if (from() == kUnboxedMint) {
6559 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
6560 Location::RequiresRegister()));
6561 summary->set_out(0, Location::RequiresRegister());
6562 } else {
6563 ASSERT(from() == kUnboxedUint32);
6564 summary->set_in(0, Location::RequiresRegister());
6565 summary->set_out(0, Location::Pair(Location::RequiresRegister(),
6566 Location::RequiresRegister()));
6567 }
6568 return summary;
6569 }
6570
6571
6572 void UnboxedIntConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6573 if (from() == kUnboxedMint) {
6574 PairLocation* in_pair = locs()->in(0).AsPairLocation();
6575 Register in_lo = in_pair->At(0).reg();
6576 Register out = locs()->out(0).reg();
6577 // Copy low word.
6578 __ mov(out, Operand(in_lo));
6579 } else {
6580 ASSERT(from() == kUnboxedUint32);
6581 Register in = locs()->in(0).reg();
6582 PairLocation* out_pair = locs()->out(0).AsPairLocation();
6583 Register out_lo = out_pair->At(0).reg();
6584 Register out_hi = out_pair->At(1).reg();
6585 // Copy low word.
6586 __ mov(out_lo, Operand(in));
6587 // Zero upper word.
6588 __ eor(out_hi, out_hi, Operand(out_hi));
6589 }
6590 }
6591
6592
6276 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, 6593 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate,
6277 bool opt) const { 6594 bool opt) const {
6278 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); 6595 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall);
6279 } 6596 }
6280 6597
6281 6598
6282 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6599 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6283 compiler->GenerateRuntimeCall(token_pos(), 6600 compiler->GenerateRuntimeCall(token_pos(),
6284 deopt_id(), 6601 deopt_id(),
6285 kThrowRuntimeEntry, 6602 kThrowRuntimeEntry,
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
6501 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); 6818 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs());
6502 #if defined(DEBUG) 6819 #if defined(DEBUG)
6503 __ LoadImmediate(R4, kInvalidObjectPointer); 6820 __ LoadImmediate(R4, kInvalidObjectPointer);
6504 __ LoadImmediate(R5, kInvalidObjectPointer); 6821 __ LoadImmediate(R5, kInvalidObjectPointer);
6505 #endif 6822 #endif
6506 } 6823 }
6507 6824
6508 } // namespace dart 6825 } // namespace dart
6509 6826
6510 #endif // defined TARGET_ARCH_ARM 6827 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698