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

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

Issue 11344011: Relational comparisons for unboxed mints. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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.h ('k') | no next file » | 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) 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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
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 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 __ LoadObject(result, compiler->bool_true()); 638 __ LoadObject(result, compiler->bool_true());
639 __ Bind(&done); 639 __ Bind(&done);
640 } 640 }
641 } 641 }
642 642
643 643
644 static Condition TokenKindToMintCondition(Token::Kind kind) { 644 static Condition TokenKindToMintCondition(Token::Kind kind) {
645 switch (kind) { 645 switch (kind) {
646 case Token::kEQ: return EQUAL; 646 case Token::kEQ: return EQUAL;
647 case Token::kNE: return NOT_EQUAL; 647 case Token::kNE: return NOT_EQUAL;
648 case Token::kLT: return BELOW;
649 case Token::kGT: return ABOVE;
650 case Token::kLTE: return BELOW_EQUAL;
651 case Token::kGTE: return ABOVE_EQUAL;
648 default: 652 default:
649 UNIMPLEMENTED(); 653 UNREACHABLE();
650 return OVERFLOW; 654 return OVERFLOW;
651 } 655 }
652 } 656 }
653 657
654 658
655 static void EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler, 659 static void EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler,
656 const LocationSummary& locs, 660 const LocationSummary& locs,
657 Token::Kind kind, 661 Token::Kind kind,
658 BranchInstr* branch) { 662 BranchInstr* branch) {
659 ASSERT(Token::IsEqualityOperator(kind)); 663 ASSERT(Token::IsEqualityOperator(kind));
(...skipping 15 matching lines...) Expand all
675 __ j(true_condition, &is_true); 679 __ j(true_condition, &is_true);
676 __ LoadObject(result, compiler->bool_false()); 680 __ LoadObject(result, compiler->bool_false());
677 __ jmp(&done); 681 __ jmp(&done);
678 __ Bind(&is_true); 682 __ Bind(&is_true);
679 __ LoadObject(result, compiler->bool_true()); 683 __ LoadObject(result, compiler->bool_true());
680 __ Bind(&done); 684 __ Bind(&done);
681 } 685 }
682 } 686 }
683 687
684 688
689 static void EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler,
690 const LocationSummary& locs,
691 Token::Kind kind,
692 BranchInstr* branch) {
693 XmmRegister left = locs.in(0).xmm_reg();
694 XmmRegister right = locs.in(1).xmm_reg();
695 Register lo = locs.temp(0).reg();
696 Register hi = locs.temp(1).reg();
697
698 __ pextrd(lo, left, Immediate(0)); // Lower half
699 __ pextrd(hi, left, Immediate(1)); // Upper half
700 __ subl(ESP, Immediate(2 * kWordSize));
701 __ movq(Address(ESP, 0), right);
702 Label compare_lo, compare_done;
703 __ cmpl(hi, Address(ESP, 1 * kWordSize));
704 __ j(EQUAL, &compare_lo);
705 __ jmp(&compare_done);
706 __ Bind(&compare_lo);
707 __ cmpl(lo, Address(ESP, 0 * kWordSize));
Vyacheslav Egorov (Google) 2012/10/29 12:46:40 can you benchmark another pattern: extract highe
708
709 __ Bind(&compare_done);
710 // Use popl to restore stack instead of add(ESP...) to preserve flags.
711 __ popl(lo);
712 __ popl(lo);
713 Condition true_condition = TokenKindToMintCondition(kind);
714 if (branch != NULL) {
715 branch->EmitBranchOnCondition(compiler, true_condition);
716 } else {
717 Register result = locs.out().reg();
718 Label done, is_true;
719 __ j(true_condition, &is_true);
720 __ LoadObject(result, compiler->bool_false());
721 __ jmp(&done);
722 __ Bind(&is_true);
723 __ LoadObject(result, compiler->bool_true());
724 __ Bind(&done);
725 }
726 }
727
728
685 static Condition TokenKindToDoubleCondition(Token::Kind kind) { 729 static Condition TokenKindToDoubleCondition(Token::Kind kind) {
686 switch (kind) { 730 switch (kind) {
687 case Token::kEQ: return EQUAL; 731 case Token::kEQ: return EQUAL;
688 case Token::kNE: return NOT_EQUAL; 732 case Token::kNE: return NOT_EQUAL;
689 case Token::kLT: return BELOW; 733 case Token::kLT: return BELOW;
690 case Token::kGT: return ABOVE; 734 case Token::kGT: return ABOVE;
691 case Token::kLTE: return BELOW_EQUAL; 735 case Token::kLTE: return BELOW_EQUAL;
692 case Token::kGTE: return ABOVE_EQUAL; 736 case Token::kGTE: return ABOVE_EQUAL;
693 default: 737 default:
694 UNREACHABLE(); 738 UNREACHABLE();
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 } 838 }
795 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; 839 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
796 __ CompareObject(EAX, compiler->bool_true()); 840 __ CompareObject(EAX, compiler->bool_true());
797 branch->EmitBranchOnCondition(compiler, branch_condition); 841 branch->EmitBranchOnCondition(compiler, branch_condition);
798 } 842 }
799 843
800 844
801 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { 845 LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
802 const intptr_t kNumInputs = 2; 846 const intptr_t kNumInputs = 2;
803 const intptr_t kNumTemps = 0; 847 const intptr_t kNumTemps = 0;
848 if (operands_class_id() == kMintCid) {
849 const intptr_t kNumTemps = 2;
850 LocationSummary* locs =
851 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
852 locs->set_in(0, Location::RequiresXmmRegister());
853 locs->set_in(1, Location::RequiresXmmRegister());
854 locs->set_temp(0, Location::RequiresRegister());
855 locs->set_temp(1, Location::RequiresRegister());
856 locs->set_out(Location::RequiresRegister());
857 return locs;
858 }
804 if (operands_class_id() == kDoubleCid) { 859 if (operands_class_id() == kDoubleCid) {
805 LocationSummary* summary = 860 LocationSummary* summary =
806 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 861 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
807 summary->set_in(0, Location::RequiresXmmRegister()); 862 summary->set_in(0, Location::RequiresXmmRegister());
808 summary->set_in(1, Location::RequiresXmmRegister()); 863 summary->set_in(1, Location::RequiresXmmRegister());
809 summary->set_out(Location::RequiresRegister()); 864 summary->set_out(Location::RequiresRegister());
810 return summary; 865 return summary;
811 } else if (operands_class_id() == kSmiCid) { 866 } else if (operands_class_id() == kSmiCid) {
812 LocationSummary* summary = 867 LocationSummary* summary =
813 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 868 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
(...skipping 10 matching lines...) Expand all
824 locs->set_out(Location::RegisterLocation(EAX)); 879 locs->set_out(Location::RegisterLocation(EAX));
825 return locs; 880 return locs;
826 } 881 }
827 882
828 883
829 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 884 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
830 if (operands_class_id() == kSmiCid) { 885 if (operands_class_id() == kSmiCid) {
831 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); 886 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL);
832 return; 887 return;
833 } 888 }
889 if (operands_class_id() == kMintCid) {
890 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL);
891 return;
892 }
834 if (operands_class_id() == kDoubleCid) { 893 if (operands_class_id() == kDoubleCid) {
835 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); 894 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL);
836 return; 895 return;
837 } 896 }
838 897
839 // Push arguments for the call. 898 // Push arguments for the call.
840 // TODO(fschneider): Split this instruction into different types to avoid 899 // TODO(fschneider): Split this instruction into different types to avoid
841 // explicitly pushing arguments to the call here. 900 // explicitly pushing arguments to the call here.
842 Register left = locs()->in(0).reg(); 901 Register left = locs()->in(0).reg();
843 Register right = locs()->in(1).reg(); 902 Register right = locs()->in(1).reg();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
883 locs()); 942 locs());
884 } 943 }
885 944
886 945
887 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, 946 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
888 BranchInstr* branch) { 947 BranchInstr* branch) {
889 if (operands_class_id() == kSmiCid) { 948 if (operands_class_id() == kSmiCid) {
890 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); 949 EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
891 return; 950 return;
892 } 951 }
952 if (operands_class_id() == kMintCid) {
953 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch);
954 return;
955 }
893 if (operands_class_id() == kDoubleCid) { 956 if (operands_class_id() == kDoubleCid) {
894 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); 957 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
895 return; 958 return;
896 } 959 }
897 EmitNativeCode(compiler); 960 EmitNativeCode(compiler);
898 __ CompareObject(EAX, compiler->bool_true()); 961 __ CompareObject(EAX, compiler->bool_true());
899 branch->EmitBranchOnCondition(compiler, EQUAL); 962 branch->EmitBranchOnCondition(compiler, EQUAL);
900 } 963 }
901 964
902 965
(...skipping 1534 matching lines...) Expand 10 before | Expand all | Expand 10 after
2437 case Token::kBIT_AND: __ andpd(left, right); break; 2500 case Token::kBIT_AND: __ andpd(left, right); break;
2438 case Token::kBIT_OR: __ orpd(left, right); break; 2501 case Token::kBIT_OR: __ orpd(left, right); break;
2439 case Token::kBIT_XOR: __ xorpd(left, right); break; 2502 case Token::kBIT_XOR: __ xorpd(left, right); break;
2440 case Token::kADD: 2503 case Token::kADD:
2441 case Token::kSUB: { 2504 case Token::kSUB: {
2442 Register lo = locs()->temp(0).reg(); 2505 Register lo = locs()->temp(0).reg();
2443 Register hi = locs()->temp(1).reg(); 2506 Register hi = locs()->temp(1).reg();
2444 Label* deopt = compiler->AddDeoptStub(deopt_id(), 2507 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2445 kDeoptBinaryMintOp); 2508 kDeoptBinaryMintOp);
2446 Label done, overflow; 2509 Label done, overflow;
2447 __ pextrd(lo, right, Immediate(0)); // Lower half left 2510 __ pextrd(lo, right, Immediate(0)); // Lower half
2448 __ pextrd(hi, right, Immediate(1)); // Upper half left 2511 __ pextrd(hi, right, Immediate(1)); // Upper half
2449 __ subl(ESP, Immediate(2 * kWordSize)); 2512 __ subl(ESP, Immediate(2 * kWordSize));
2450 __ movq(Address(ESP, 0), left); 2513 __ movq(Address(ESP, 0), left);
2451 if (op_kind() == Token::kADD) { 2514 if (op_kind() == Token::kADD) {
2452 __ addl(Address(ESP, 0), lo); 2515 __ addl(Address(ESP, 0), lo);
2453 __ adcl(Address(ESP, 1 * kWordSize), hi); 2516 __ adcl(Address(ESP, 1 * kWordSize), hi);
2454 } else { 2517 } else {
2455 __ subl(Address(ESP, 0), lo); 2518 __ subl(Address(ESP, 0), lo);
2456 __ sbbl(Address(ESP, 1 * kWordSize), hi); 2519 __ sbbl(Address(ESP, 1 * kWordSize), hi);
2457 } 2520 }
2458 __ j(OVERFLOW, &overflow); 2521 __ j(OVERFLOW, &overflow);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2558 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. 2621 __ pcmpeqq(XMM0, XMM0); // Generate all 1's.
2559 __ pxor(value, XMM0); 2622 __ pxor(value, XMM0);
2560 } 2623 }
2561 2624
2562 2625
2563 } // namespace dart 2626 } // namespace dart
2564 2627
2565 #undef __ 2628 #undef __
2566 2629
2567 #endif // defined TARGET_ARCH_X64 2630 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698