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

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

Issue 754763003: Version 1.8.3 (Closed) Base URL: http://dart.googlecode.com/svn/branches/1.8/
Patch Set: Created 6 years 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 | « dart/runtime/vm/intermediate_language.cc ('k') | dart/runtime/vm/intermediate_language_ia32.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 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 return VS; 547 return VS;
548 } 548 }
549 } 549 }
550 550
551 551
552 static Condition EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler, 552 static Condition EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler,
553 LocationSummary* locs, 553 LocationSummary* locs,
554 Token::Kind kind) { 554 Token::Kind kind) {
555 ASSERT(Token::IsEqualityOperator(kind)); 555 ASSERT(Token::IsEqualityOperator(kind));
556 PairLocation* left_pair = locs->in(0).AsPairLocation(); 556 PairLocation* left_pair = locs->in(0).AsPairLocation();
557 Register left1 = left_pair->At(0).reg(); 557 Register left_lo = left_pair->At(0).reg();
558 Register left2 = left_pair->At(1).reg(); 558 Register left_hi = left_pair->At(1).reg();
559 PairLocation* right_pair = locs->in(1).AsPairLocation(); 559 PairLocation* right_pair = locs->in(1).AsPairLocation();
560 Register right1 = right_pair->At(0).reg(); 560 Register right_lo = right_pair->At(0).reg();
561 Register right2 = right_pair->At(1).reg(); 561 Register right_hi = right_pair->At(1).reg();
562 562
563 // Compare lower. 563 // Compare lower.
564 __ cmp(left1, Operand(right1)); 564 __ cmp(left_lo, Operand(right_lo));
565 // Compare upper if lower is equal. 565 // Compare upper if lower is equal.
566 __ cmp(left2, Operand(right2), EQ); 566 __ cmp(left_hi, Operand(right_hi), EQ);
567 return TokenKindToMintCondition(kind); 567 return TokenKindToMintCondition(kind);
568 } 568 }
569 569
570 570
571 static Condition EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler, 571 static Condition EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler,
572 LocationSummary* locs, 572 LocationSummary* locs,
573 Token::Kind kind) { 573 Token::Kind kind) {
574 PairLocation* left_pair = locs->in(0).AsPairLocation(); 574 PairLocation* left_pair = locs->in(0).AsPairLocation();
575 Register left1 = left_pair->At(0).reg(); 575 Register left_lo = left_pair->At(0).reg();
576 Register left2 = left_pair->At(1).reg(); 576 Register left_hi = left_pair->At(1).reg();
577 PairLocation* right_pair = locs->in(1).AsPairLocation(); 577 PairLocation* right_pair = locs->in(1).AsPairLocation();
578 Register right1 = right_pair->At(0).reg(); 578 Register right_lo = right_pair->At(0).reg();
579 Register right2 = right_pair->At(1).reg(); 579 Register right_hi = right_pair->At(1).reg();
580 580
581 Register out = locs->temp(0).reg(); 581 Register out = locs->temp(0).reg();
582 582
583 // 64-bit comparison 583 // 64-bit comparison
584 Condition hi_true_cond, hi_false_cond, lo_false_cond; 584 Condition hi_true_cond, hi_false_cond, lo_false_cond;
585 switch (kind) { 585 switch (kind) {
586 case Token::kLT: 586 case Token::kLT:
587 case Token::kLTE: 587 case Token::kLTE:
588 hi_true_cond = LT; 588 hi_true_cond = LT;
589 hi_false_cond = GT; 589 hi_false_cond = GT;
590 lo_false_cond = (kind == Token::kLT) ? CS : HI; 590 lo_false_cond = (kind == Token::kLT) ? CS : HI;
591 break; 591 break;
592 case Token::kGT: 592 case Token::kGT:
593 case Token::kGTE: 593 case Token::kGTE:
594 hi_true_cond = GT; 594 hi_true_cond = GT;
595 hi_false_cond = LT; 595 hi_false_cond = LT;
596 lo_false_cond = (kind == Token::kGT) ? LS : CC; 596 lo_false_cond = (kind == Token::kGT) ? LS : CC;
597 break; 597 break;
598 default: 598 default:
599 UNREACHABLE(); 599 UNREACHABLE();
600 hi_true_cond = hi_false_cond = lo_false_cond = VS; 600 hi_true_cond = hi_false_cond = lo_false_cond = VS;
601 } 601 }
602 602
603 Label is_true, is_false, done; 603 Label done;
604 // Compare upper halves first. 604 // Compare upper halves first.
605 __ cmp(left2, Operand(right2)); 605 __ cmp(left_hi, Operand(right_hi));
606 __ LoadImmediate(out, 0, hi_false_cond); 606 __ LoadImmediate(out, 0, hi_false_cond);
607 __ LoadImmediate(out, 1, hi_true_cond); 607 __ LoadImmediate(out, 1, hi_true_cond);
608 // If higher words aren't equal, skip comparing lower words. 608 // If higher words aren't equal, skip comparing lower words.
609 __ b(&done, NE); 609 __ b(&done, NE);
610 610
611 __ cmp(left1, Operand(right1)); 611 __ cmp(left_lo, Operand(right_lo));
612 __ LoadImmediate(out, 1); 612 __ LoadImmediate(out, 1);
613 __ LoadImmediate(out, 0, lo_false_cond); 613 __ LoadImmediate(out, 0, lo_false_cond);
614 __ Bind(&done); 614 __ Bind(&done);
615 615
616 return NegateCondition(lo_false_cond); 616 return NegateCondition(lo_false_cond);
617 } 617 }
618 618
619 619
620 static Condition TokenKindToDoubleCondition(Token::Kind kind) { 620 static Condition TokenKindToDoubleCondition(Token::Kind kind) {
621 switch (kind) { 621 switch (kind) {
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
822 const intptr_t kNumInputs = 2; 822 const intptr_t kNumInputs = 2;
823 const intptr_t kNumTemps = 0; 823 const intptr_t kNumTemps = 0;
824 if (operation_cid() == kMintCid) { 824 if (operation_cid() == kMintCid) {
825 const intptr_t kNumTemps = 1; 825 const intptr_t kNumTemps = 1;
826 LocationSummary* locs = new(isolate) LocationSummary( 826 LocationSummary* locs = new(isolate) LocationSummary(
827 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 827 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
828 locs->set_in(0, Location::Pair(Location::RequiresRegister(), 828 locs->set_in(0, Location::Pair(Location::RequiresRegister(),
829 Location::RequiresRegister())); 829 Location::RequiresRegister()));
830 locs->set_in(1, Location::Pair(Location::RequiresRegister(), 830 locs->set_in(1, Location::Pair(Location::RequiresRegister(),
831 Location::RequiresRegister())); 831 Location::RequiresRegister()));
832 locs->set_temp(0, Location::RequiresRegister()); 832 locs->set_temp(0, Location::RequiresRegister()); // TODO(regis): Improve.
833 locs->set_out(0, Location::RequiresRegister()); 833 locs->set_out(0, Location::RequiresRegister());
834 return locs; 834 return locs;
835 } 835 }
836 if (operation_cid() == kDoubleCid) { 836 if (operation_cid() == kDoubleCid) {
837 LocationSummary* summary = new(isolate) LocationSummary( 837 LocationSummary* summary = new(isolate) LocationSummary(
838 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 838 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
839 summary->set_in(0, Location::RequiresFpuRegister()); 839 summary->set_in(0, Location::RequiresFpuRegister());
840 summary->set_in(1, Location::RequiresFpuRegister()); 840 summary->set_in(1, Location::RequiresFpuRegister());
841 summary->set_out(0, Location::RequiresRegister()); 841 summary->set_out(0, Location::RequiresRegister());
842 return summary; 842 return summary;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
896 896
897 897
898 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, 898 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
899 BranchInstr* branch) { 899 BranchInstr* branch) {
900 BranchLabels labels = compiler->CreateBranchLabels(branch); 900 BranchLabels labels = compiler->CreateBranchLabels(branch);
901 Condition true_condition = EmitComparisonCode(compiler, labels); 901 Condition true_condition = EmitComparisonCode(compiler, labels);
902 902
903 if (operation_cid() == kSmiCid) { 903 if (operation_cid() == kSmiCid) {
904 EmitBranchOnCondition(compiler, true_condition, labels); 904 EmitBranchOnCondition(compiler, true_condition, labels);
905 } else if (operation_cid() == kMintCid) { 905 } else if (operation_cid() == kMintCid) {
906 const Register result = locs()->temp(0).reg(); 906 const Register result = locs()->temp(0).reg(); // TODO(regis): Improve.
907 __ CompareImmediate(result, 1); 907 __ CompareImmediate(result, 1);
908 __ b(labels.true_label, EQ); 908 __ b(labels.true_label, EQ);
909 __ b(labels.false_label, NE); 909 __ b(labels.false_label, NE);
910 } else if (operation_cid() == kDoubleCid) { 910 } else if (operation_cid() == kDoubleCid) {
911 Label* nan_result = (true_condition == NE) ? 911 Label* nan_result = (true_condition == NE) ?
912 labels.true_label : labels.false_label; 912 labels.true_label : labels.false_label;
913 __ b(nan_result, VS); 913 __ b(nan_result, VS);
914 EmitBranchOnCondition(compiler, true_condition, labels); 914 EmitBranchOnCondition(compiler, true_condition, labels);
915 } 915 }
916 } 916 }
(...skipping 2862 matching lines...) Expand 10 before | Expand all | Expand 10 after
3779 __ StoreToOffset(kWord, 3779 __ StoreToOffset(kWord,
3780 temp, 3780 temp,
3781 out, 3781 out,
3782 Mint::value_offset() - kHeapObjectTag + kWordSize); 3782 Mint::value_offset() - kHeapObjectTag + kWordSize);
3783 __ Bind(&done); 3783 __ Bind(&done);
3784 } 3784 }
3785 } 3785 }
3786 3786
3787 3787
3788 LocationSummary* BoxInt64Instr::MakeLocationSummary(Isolate* isolate, 3788 LocationSummary* BoxInt64Instr::MakeLocationSummary(Isolate* isolate,
3789 bool opt) const { 3789 bool opt) const {
3790 const intptr_t kNumInputs = 1; 3790 const intptr_t kNumInputs = 1;
3791 const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1; 3791 const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1;
3792 LocationSummary* summary = new(isolate) LocationSummary( 3792 LocationSummary* summary = new(isolate) LocationSummary(
3793 isolate, 3793 isolate,
3794 kNumInputs, 3794 kNumInputs,
3795 kNumTemps, 3795 kNumTemps,
3796 ValueFitsSmi() ? LocationSummary::kNoCall 3796 ValueFitsSmi() ? LocationSummary::kNoCall
3797 : LocationSummary::kCallOnSlowPath); 3797 : LocationSummary::kCallOnSlowPath);
3798 summary->set_in(0, Location::Pair(Location::RequiresRegister(), 3798 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
3799 Location::RequiresRegister())); 3799 Location::RequiresRegister()));
(...skipping 2400 matching lines...) Expand 10 before | Expand all | Expand 10 after
6200 if (shift == 32) { 6200 if (shift == 32) {
6201 __ mov(out_hi, Operand(left_lo)); 6201 __ mov(out_hi, Operand(left_lo));
6202 } else { 6202 } else {
6203 __ Lsl(out_hi, left_lo, Operand(shift - 32)); 6203 __ Lsl(out_hi, left_lo, Operand(shift - 32));
6204 } 6204 }
6205 __ mov(out_lo, Operand(0)); 6205 __ mov(out_lo, Operand(0));
6206 } 6206 }
6207 // Check for overflow. 6207 // Check for overflow.
6208 if (can_overflow()) { 6208 if (can_overflow()) {
6209 // Compare high word from input with shifted high word from output. 6209 // Compare high word from input with shifted high word from output.
6210 if (shift > 31) { 6210 // If shift > 32, also compare low word from input with high word from
6211 __ cmp(left_hi, Operand(out_hi)); 6211 // output shifted back shift - 32.
6212 if (shift > 32) {
6213 __ cmp(left_lo, Operand(out_hi, ASR, shift - 32));
6214 __ cmp(left_hi, Operand(out_hi, ASR, 31), EQ);
6215 } else if (shift == 32) {
6216 __ cmp(left_hi, Operand(out_hi, ASR, 31));
6212 } else { 6217 } else {
6213 __ cmp(left_hi, Operand(out_hi, ASR, shift)); 6218 __ cmp(left_hi, Operand(out_hi, ASR, shift));
6214 } 6219 }
6215 // Overflow if they aren't equal. 6220 // Overflow if they aren't equal.
6216 __ b(deopt, NE); 6221 __ b(deopt, NE);
6217 } 6222 }
6218 break; 6223 break;
6219 } 6224 }
6220 default: 6225 default:
6221 UNREACHABLE(); 6226 UNREACHABLE();
6222 } 6227 }
6223 } else { 6228 } else {
6224 // Code for a variable shift amount. 6229 // Code for a variable shift amount.
6225 Register shift = locs()->in(1).reg(); 6230 Register shift = locs()->in(1).reg();
6226 6231
6227 // Untag shift count. 6232 // Untag shift count.
6228 __ SmiUntag(shift); 6233 __ SmiUntag(shift);
6229 6234
6230 // Deopt if shift is larger than 63 or less than 0. 6235 // Deopt if shift is larger than 63 or less than 0.
6231 if (has_shift_count_check()) { 6236 if (has_shift_count_check()) {
6232 __ CompareImmediate(shift, kMintShiftCountLimit); 6237 __ CompareImmediate(shift, kMintShiftCountLimit);
6233 __ b(deopt, HI); 6238 __ b(deopt, HI);
6234 } 6239 }
6235 6240
6236 __ mov(out_lo, Operand(left_lo));
6237 __ mov(out_hi, Operand(left_hi));
6238
6239 switch (op_kind()) { 6241 switch (op_kind()) {
6240 case Token::kSHR: { 6242 case Token::kSHR: {
6241 __ cmp(shift, Operand(32)); 6243 __ rsbs(IP, shift, Operand(32));
6242 6244 __ sub(IP, shift, Operand(32), MI);
6243 __ mov(out_lo, Operand(out_hi), HI); 6245 __ mov(out_lo, Operand(left_hi, ASR, IP), MI);
6244 __ Asr(out_hi, out_hi, Operand(31), HI); 6246 __ mov(out_lo, Operand(left_lo, LSR, shift), PL);
6245 __ sub(shift, shift, Operand(32), HI); 6247 __ orr(out_lo, out_lo, Operand(left_hi, LSL, IP), PL);
6246 6248 __ mov(out_hi, Operand(left_hi, ASR, shift));
6247 __ rsb(IP, shift, Operand(32));
6248 __ mov(IP, Operand(out_hi, LSL, IP));
6249 __ orr(out_lo, IP, Operand(out_lo, LSR, shift));
6250 __ Asr(out_hi, out_hi, shift);
6251 break; 6249 break;
6252 } 6250 }
6253 case Token::kSHL: { 6251 case Token::kSHL: {
6254 __ rsbs(IP, shift, Operand(32)); 6252 __ rsbs(IP, shift, Operand(32));
6255 __ sub(IP, shift, Operand(32), MI); 6253 __ sub(IP, shift, Operand(32), MI);
6256 __ mov(out_hi, Operand(out_lo, LSL, IP), MI); 6254 __ mov(out_hi, Operand(left_lo, LSL, IP), MI);
6257 __ mov(out_hi, Operand(out_hi, LSL, shift), PL); 6255 __ mov(out_hi, Operand(left_hi, LSL, shift), PL);
6258 __ orr(out_hi, out_hi, Operand(out_lo, LSR, IP), PL); 6256 __ orr(out_hi, out_hi, Operand(left_lo, LSR, IP), PL);
6259 __ mov(out_lo, Operand(out_lo, LSL, shift)); 6257 __ mov(out_lo, Operand(left_lo, LSL, shift));
6260 6258
6261 // Check for overflow. 6259 // Check for overflow.
6262 if (can_overflow()) { 6260 if (can_overflow()) {
6261 // If shift > 32, compare low word from input with high word from
6262 // output shifted back shift - 32.
6263 __ mov(IP, Operand(out_hi, ASR, IP), MI);
6264 __ mov(IP, Operand(left_lo), PL); // No test if shift <= 32.
6265 __ cmp(left_lo, Operand(IP));
6263 // Compare high word from input with shifted high word from output. 6266 // Compare high word from input with shifted high word from output.
6264 __ cmp(left_hi, Operand(out_hi, ASR, shift)); 6267 __ cmp(left_hi, Operand(out_hi, ASR, shift), EQ);
6265 // Overflow if they aren't equal. 6268 // Overflow if they aren't equal.
6266 __ b(deopt, NE); 6269 __ b(deopt, NE);
6267 } 6270 }
6268 break; 6271 break;
6269 } 6272 }
6270 default: 6273 default:
6271 UNREACHABLE(); 6274 UNREACHABLE();
6272 } 6275 }
6273 } 6276 }
6274 6277
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
6750 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); 6753 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs());
6751 #if defined(DEBUG) 6754 #if defined(DEBUG)
6752 __ LoadImmediate(R4, kInvalidObjectPointer); 6755 __ LoadImmediate(R4, kInvalidObjectPointer);
6753 __ LoadImmediate(R5, kInvalidObjectPointer); 6756 __ LoadImmediate(R5, kInvalidObjectPointer);
6754 #endif 6757 #endif
6755 } 6758 }
6756 6759
6757 } // namespace dart 6760 } // namespace dart
6758 6761
6759 #endif // defined TARGET_ARCH_ARM 6762 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « dart/runtime/vm/intermediate_language.cc ('k') | dart/runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698