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

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

Issue 283513002: Adds far-branches to arm64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 7 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 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 return EmitSmiComparisonOp(compiler, locs(), kind()); 484 return EmitSmiComparisonOp(compiler, locs(), kind());
485 } else { 485 } else {
486 ASSERT(operation_cid() == kDoubleCid); 486 ASSERT(operation_cid() == kDoubleCid);
487 return EmitDoubleComparisonOp(compiler, locs(), kind()); 487 return EmitDoubleComparisonOp(compiler, locs(), kind());
488 } 488 }
489 } 489 }
490 490
491 491
492 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 492 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
493 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE)); 493 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE));
494
495 Label is_true, is_false; 494 Label is_true, is_false;
496 BranchLabels labels = { &is_true, &is_false, &is_false }; 495 BranchLabels labels = { &is_true, &is_false, &is_false };
497 Condition true_condition = EmitComparisonCode(compiler, labels); 496 Condition true_condition = EmitComparisonCode(compiler, labels);
497 if ((operation_cid() == kDoubleCid) && (true_condition != NE)) {
498 // Special case for NaN comparison. Result is always false unless
499 // relational operator is !=.
500 __ b(&is_false, VS);
501 }
498 EmitBranchOnCondition(compiler, true_condition, labels); 502 EmitBranchOnCondition(compiler, true_condition, labels);
499
500 // TODO(zra): instead of branching, use the csel instruction to get 503 // TODO(zra): instead of branching, use the csel instruction to get
501 // True or False into result. 504 // True or False into result.
502 Register result = locs()->out(0).reg(); 505 Register result = locs()->out(0).reg();
503 Label done; 506 Label done;
504 __ Bind(&is_false); 507 __ Bind(&is_false);
505 __ LoadObject(result, Bool::False(), PP); 508 __ LoadObject(result, Bool::False(), PP);
506 __ b(&done); 509 __ b(&done);
507 __ Bind(&is_true); 510 __ Bind(&is_true);
508 __ LoadObject(result, Bool::True(), PP); 511 __ LoadObject(result, Bool::True(), PP);
509 __ Bind(&done); 512 __ Bind(&done);
510 } 513 }
511 514
512 515
513 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 516 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
514 BranchInstr* branch) { 517 BranchInstr* branch) {
515 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 518 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
516 519
517 BranchLabels labels = compiler->CreateBranchLabels(branch); 520 BranchLabels labels = compiler->CreateBranchLabels(branch);
518 Condition true_condition = EmitComparisonCode(compiler, labels); 521 Condition true_condition = EmitComparisonCode(compiler, labels);
522 if ((operation_cid() == kDoubleCid) && (true_condition != NE)) {
523 // Special case for NaN comparison. Result is always false unless
524 // relational operator is !=.
525 __ b(labels.false_label, VS);
526 }
519 EmitBranchOnCondition(compiler, true_condition, labels); 527 EmitBranchOnCondition(compiler, true_condition, labels);
520 } 528 }
521 529
522 530
523 LocationSummary* TestSmiInstr::MakeLocationSummary(bool opt) const { 531 LocationSummary* TestSmiInstr::MakeLocationSummary(bool opt) const {
524 const intptr_t kNumInputs = 2; 532 const intptr_t kNumInputs = 2;
525 const intptr_t kNumTemps = 0; 533 const intptr_t kNumTemps = 0;
526 LocationSummary* locs = 534 LocationSummary* locs =
527 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 535 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
528 locs->set_in(0, Location::RequiresRegister()); 536 locs->set_in(0, Location::RequiresRegister());
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 ASSERT(operation_cid() == kDoubleCid); 679 ASSERT(operation_cid() == kDoubleCid);
672 return EmitDoubleComparisonOp(compiler, locs(), kind()); 680 return EmitDoubleComparisonOp(compiler, locs(), kind());
673 } 681 }
674 } 682 }
675 683
676 684
677 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 685 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
678 Label is_true, is_false; 686 Label is_true, is_false;
679 BranchLabels labels = { &is_true, &is_false, &is_false }; 687 BranchLabels labels = { &is_true, &is_false, &is_false };
680 Condition true_condition = EmitComparisonCode(compiler, labels); 688 Condition true_condition = EmitComparisonCode(compiler, labels);
689 if ((operation_cid() == kDoubleCid) && (true_condition != NE)) {
690 // Special case for NaN comparison. Result is always false unless
691 // relational operator is !=.
692 __ b(&is_false, VS);
693 }
681 EmitBranchOnCondition(compiler, true_condition, labels); 694 EmitBranchOnCondition(compiler, true_condition, labels);
682 // TODO(zra): instead of branching, use the csel instruction to get 695 // TODO(zra): instead of branching, use the csel instruction to get
683 // True or False into result. 696 // True or False into result.
684 Register result = locs()->out(0).reg(); 697 Register result = locs()->out(0).reg();
685 Label done; 698 Label done;
686 __ Bind(&is_false); 699 __ Bind(&is_false);
687 __ LoadObject(result, Bool::False(), PP); 700 __ LoadObject(result, Bool::False(), PP);
688 __ b(&done); 701 __ b(&done);
689 __ Bind(&is_true); 702 __ Bind(&is_true);
690 __ LoadObject(result, Bool::True(), PP); 703 __ LoadObject(result, Bool::True(), PP);
691 __ Bind(&done); 704 __ Bind(&done);
692 } 705 }
693 706
694 707
695 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, 708 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
696 BranchInstr* branch) { 709 BranchInstr* branch) {
697 BranchLabels labels = compiler->CreateBranchLabels(branch); 710 BranchLabels labels = compiler->CreateBranchLabels(branch);
698 Condition true_condition = EmitComparisonCode(compiler, labels); 711 Condition true_condition = EmitComparisonCode(compiler, labels);
712 if ((operation_cid() == kDoubleCid) && (true_condition != NE)) {
713 // Special case for NaN comparison. Result is always false unless
714 // relational operator is !=.
715 __ b(labels.false_label, VS);
716 }
699 EmitBranchOnCondition(compiler, true_condition, labels); 717 EmitBranchOnCondition(compiler, true_condition, labels);
700 } 718 }
701 719
702 720
703 LocationSummary* NativeCallInstr::MakeLocationSummary(bool opt) const { 721 LocationSummary* NativeCallInstr::MakeLocationSummary(bool opt) const {
704 const intptr_t kNumInputs = 0; 722 const intptr_t kNumInputs = 0;
705 const intptr_t kNumTemps = 3; 723 const intptr_t kNumTemps = 3;
706 LocationSummary* locs = 724 LocationSummary* locs =
707 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 725 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
708 locs->set_temp(0, Location::RegisterLocation(R1)); 726 locs->set_temp(0, Location::RegisterLocation(R1));
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
766 // TODO(fschneider): Allow immediate operands for the char code. 784 // TODO(fschneider): Allow immediate operands for the char code.
767 return LocationSummary::Make(kNumInputs, 785 return LocationSummary::Make(kNumInputs,
768 Location::RequiresRegister(), 786 Location::RequiresRegister(),
769 LocationSummary::kNoCall); 787 LocationSummary::kNoCall);
770 } 788 }
771 789
772 790
773 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 791 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
774 const Register char_code = locs()->in(0).reg(); 792 const Register char_code = locs()->in(0).reg();
775 const Register result = locs()->out(0).reg(); 793 const Register result = locs()->out(0).reg();
776 __ LoadImmediate(result, 794 __ LoadImmediate(
777 reinterpret_cast<uword>(Symbols::PredefinedAddress()), PP); 795 result, reinterpret_cast<uword>(Symbols::PredefinedAddress()), PP);
778 __ AddImmediate( 796 __ AddImmediate(
779 result, result, Symbols::kNullCharCodeSymbolOffset * kWordSize, PP); 797 result, result, Symbols::kNullCharCodeSymbolOffset * kWordSize, PP);
780 __ Asr(TMP, char_code, kSmiTagShift); // Untag to use scaled adress mode. 798 __ Asr(TMP, char_code, kSmiTagShift); // Untag to use scaled adress mode.
781 __ ldr(result, Address(result, TMP, UXTX, Address::Scaled)); 799 __ ldr(result, Address(result, TMP, UXTX, Address::Scaled));
782 } 800 }
783 801
784 802
785 LocationSummary* StringToCharCodeInstr::MakeLocationSummary(bool opt) const { 803 LocationSummary* StringToCharCodeInstr::MakeLocationSummary(bool opt) const {
786 const intptr_t kNumInputs = 1; 804 const intptr_t kNumInputs = 1;
787 return LocationSummary::Make(kNumInputs, 805 return LocationSummary::Make(kNumInputs,
(...skipping 2044 matching lines...) Expand 10 before | Expand all | Expand 10 after
2832 // sarl operation masks the count to 6 bits. 2850 // sarl operation masks the count to 6 bits.
2833 const intptr_t kCountLimit = 0x3F; 2851 const intptr_t kCountLimit = 0x3F;
2834 if ((right_range == NULL) || 2852 if ((right_range == NULL) ||
2835 !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) { 2853 !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) {
2836 __ LoadImmediate(TMP2, kCountLimit, PP); 2854 __ LoadImmediate(TMP2, kCountLimit, PP);
2837 __ CompareRegisters(TMP, TMP2); 2855 __ CompareRegisters(TMP, TMP2);
2838 __ csel(TMP, TMP2, TMP, GT); 2856 __ csel(TMP, TMP2, TMP, GT);
2839 } 2857 }
2840 Register temp = locs()->temp(0).reg(); 2858 Register temp = locs()->temp(0).reg();
2841 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. 2859 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp.
2842 __ Asr(result, temp, TMP); 2860 __ asrv(result, temp, TMP);
2843 __ SmiTag(result); 2861 __ SmiTag(result);
2844 break; 2862 break;
2845 } 2863 }
2846 case Token::kDIV: { 2864 case Token::kDIV: {
2847 // Dispatches to 'Double./'. 2865 // Dispatches to 'Double./'.
2848 // TODO(srdjan): Implement as conversion to double and double division. 2866 // TODO(srdjan): Implement as conversion to double and double division.
2849 UNREACHABLE(); 2867 UNREACHABLE();
2850 break; 2868 break;
2851 } 2869 }
2852 case Token::kOR: 2870 case Token::kOR:
(...skipping 836 matching lines...) Expand 10 before | Expand all | Expand 10 after
3689 LocationSummary* locs = instr->locs(); 3707 LocationSummary* locs = instr->locs();
3690 3708
3691 const VRegister base = locs->in(0).fpu_reg(); 3709 const VRegister base = locs->in(0).fpu_reg();
3692 const VRegister exp = locs->in(1).fpu_reg(); 3710 const VRegister exp = locs->in(1).fpu_reg();
3693 const VRegister result = locs->out(0).fpu_reg(); 3711 const VRegister result = locs->out(0).fpu_reg();
3694 const VRegister saved_base = locs->temp(0).fpu_reg(); 3712 const VRegister saved_base = locs->temp(0).fpu_reg();
3695 ASSERT((base == result) && (result != saved_base)); 3713 ASSERT((base == result) && (result != saved_base));
3696 3714
3697 Label skip_call, try_sqrt, check_base, return_nan, do_pow; 3715 Label skip_call, try_sqrt, check_base, return_nan, do_pow;
3698 __ fmovdd(saved_base, base); 3716 __ fmovdd(saved_base, base);
3699 __ b(&do_pow);
3700 __ LoadDImmediate(result, 1.0, PP); 3717 __ LoadDImmediate(result, 1.0, PP);
3701 // exponent == 0.0 -> return 1.0; 3718 // exponent == 0.0 -> return 1.0;
3702 __ fcmpdz(exp); 3719 __ fcmpdz(exp);
3703 __ b(&check_base, VS); // NaN -> check base. 3720 __ b(&check_base, VS); // NaN -> check base.
3704 __ b(&skip_call, EQ); // exp is 0.0, result is 1.0. 3721 __ b(&skip_call, EQ); // exp is 0.0, result is 1.0.
3705 3722
3706 // exponent == 1.0 ? 3723 // exponent == 1.0 ?
3707 __ fcmpd(exp, result); 3724 __ fcmpd(exp, result);
3708 Label return_base; 3725 Label return_base;
3709 __ b(&return_base, EQ); 3726 __ b(&return_base, EQ);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3755 // base == -Infinity -> call pow; 3772 // base == -Infinity -> call pow;
3756 __ fcmpd(saved_base, result); 3773 __ fcmpd(saved_base, result);
3757 __ b(&do_pow, EQ); 3774 __ b(&do_pow, EQ);
3758 3775
3759 // exponent == 0.5 ? 3776 // exponent == 0.5 ?
3760 __ LoadDImmediate(result, 0.5, PP); 3777 __ LoadDImmediate(result, 0.5, PP);
3761 __ fcmpd(exp, result); 3778 __ fcmpd(exp, result);
3762 __ b(&do_pow, NE); 3779 __ b(&do_pow, NE);
3763 3780
3764 // base == 0 -> return 0; 3781 // base == 0 -> return 0;
3765 __ fcmpdz(base); 3782 __ fcmpdz(saved_base);
3766 __ b(&return_zero, EQ); 3783 __ b(&return_zero, EQ);
3767 3784
3768 __ fsqrtd(result, saved_base); 3785 __ fsqrtd(result, saved_base);
3769 __ b(&skip_call); 3786 __ b(&skip_call);
3770 3787
3771 __ Bind(&return_zero); 3788 __ Bind(&return_zero);
3772 __ LoadDImmediate(result, 0.0, PP); 3789 __ LoadDImmediate(result, 0.0, PP);
3773 __ b(&skip_call); 3790 __ b(&skip_call);
3774 3791
3775 __ Bind(&do_pow); 3792 __ Bind(&do_pow);
(...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after
4359 compiler->GenerateCall(token_pos(), 4376 compiler->GenerateCall(token_pos(),
4360 &label, 4377 &label,
4361 PcDescriptors::kOther, 4378 PcDescriptors::kOther,
4362 locs()); 4379 locs());
4363 __ Drop(ArgumentCount()); // Discard arguments. 4380 __ Drop(ArgumentCount()); // Discard arguments.
4364 } 4381 }
4365 4382
4366 } // namespace dart 4383 } // namespace dart
4367 4384
4368 #endif // defined TARGET_ARCH_ARM64 4385 #endif // defined TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698