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

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

Issue 2937933002: Reduce copying, redundancy & repetition for codegen of comparison instructions (Closed)
Patch Set: Created 3 years, 6 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
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_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 "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels); 593 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
594 } else if (operation_cid() == kMintCid) { 594 } else if (operation_cid() == kMintCid) {
595 return EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), labels); 595 return EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), labels);
596 } else { 596 } else {
597 ASSERT(operation_cid() == kDoubleCid); 597 ASSERT(operation_cid() == kDoubleCid);
598 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); 598 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
599 } 599 }
600 } 600 }
601 601
602 602
603 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 603 template <intptr_t N,
604 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 604 typename ThrowsTrait,
605 605 template <typename Impure, typename Pure> class CSETrait>
606 void TemplateComparison<N, ThrowsTrait, CSETrait>::EmitNativeCode(
607 FlowGraphCompiler* compiler) {
606 Label is_true, is_false; 608 Label is_true, is_false;
607 BranchLabels labels = {&is_true, &is_false, &is_false}; 609 BranchLabels labels = {&is_true, &is_false, &is_false};
608 Condition true_condition = EmitComparisonCode(compiler, labels); 610 Condition true_condition = EmitComparisonCode(compiler, labels);
609 EmitBranchOnCondition(compiler, true_condition, labels); 611 if (true_condition != INVALID_CONDITION) {
612 EmitBranchOnCondition(compiler, true_condition, labels);
613 }
610 614
611 Register result = locs()->out(0).reg(); 615 Register result = this->locs()->out(0).reg();
612 Label done; 616 Label done;
613 __ Bind(&is_false); 617 __ Bind(&is_false);
614 __ LoadObject(result, Bool::False()); 618 __ LoadObject(result, Bool::False());
615 __ jmp(&done, Assembler::kNearJump); 619 __ jmp(&done, Assembler::kNearJump);
616 __ Bind(&is_true); 620 __ Bind(&is_true);
617 __ LoadObject(result, Bool::True()); 621 __ LoadObject(result, Bool::True());
618 __ Bind(&done); 622 __ Bind(&done);
619 } 623 }
620 624
621 625
622 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 626 // IA32 compiler needs this to link.
623 BranchInstr* branch) { 627 template <>
624 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 628 void TemplateComparison<2, Throws, NoCSE>::EmitNativeCode(
629 FlowGraphCompiler* compiler) {
630 UNREACHABLE();
631 }
625 632
633
634 template <intptr_t N,
635 typename ThrowsTrait,
636 template <typename Impure, typename Pure> class CSETrait>
637 void TemplateComparison<N, ThrowsTrait, CSETrait>::EmitBranchCode(
638 FlowGraphCompiler* compiler,
639 BranchInstr* branch) {
626 BranchLabels labels = compiler->CreateBranchLabels(branch); 640 BranchLabels labels = compiler->CreateBranchLabels(branch);
627 Condition true_condition = EmitComparisonCode(compiler, labels); 641 Condition true_condition = EmitComparisonCode(compiler, labels);
628 EmitBranchOnCondition(compiler, true_condition, labels); 642 if (true_condition != INVALID_CONDITION) {
643 EmitBranchOnCondition(compiler, true_condition, labels);
644 }
629 } 645 }
630 646
631 647
648 // IA32 compiler needs this to link.
649 template <>
650 void TemplateComparison<2, Throws, NoCSE>::EmitBranchCode(
651 FlowGraphCompiler* compiler,
652 BranchInstr* branch) {
653 UNREACHABLE();
654 }
655
656
657 // Explicit template instantiations.
658 template void TemplateComparison<1, NoThrow, Pure>::EmitNativeCode(
659 FlowGraphCompiler*);
660 template void TemplateComparison<2, NoThrow, Pure>::EmitNativeCode(
661 FlowGraphCompiler*);
662 template void TemplateComparison<1, NoThrow, Pure>::EmitBranchCode(
663 FlowGraphCompiler* compiler,
664 BranchInstr* branch);
665 template void TemplateComparison<2, NoThrow, Pure>::EmitBranchCode(
666 FlowGraphCompiler* compiler,
667 BranchInstr* branch);
668
669
632 LocationSummary* TestSmiInstr::MakeLocationSummary(Zone* zone, bool opt) const { 670 LocationSummary* TestSmiInstr::MakeLocationSummary(Zone* zone, bool opt) const {
633 const intptr_t kNumInputs = 2; 671 const intptr_t kNumInputs = 2;
634 const intptr_t kNumTemps = 0; 672 const intptr_t kNumTemps = 0;
635 LocationSummary* locs = new (zone) 673 LocationSummary* locs = new (zone)
636 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 674 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
637 locs->set_in(0, Location::RequiresRegister()); 675 locs->set_in(0, Location::RequiresRegister());
638 // Only one input can be a constant operand. The case of two constant 676 // Only one input can be a constant operand. The case of two constant
639 // operands should be handled by constant propagation. 677 // operands should be handled by constant propagation.
640 locs->set_in(1, Location::RegisterOrConstant(right())); 678 locs->set_in(1, Location::RegisterOrConstant(right()));
641 return locs; 679 return locs;
642 } 680 }
643 681
644 682
645 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 683 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
646 BranchLabels labels) { 684 BranchLabels labels) {
647 Register left = locs()->in(0).reg(); 685 Register left = locs()->in(0).reg();
648 Location right = locs()->in(1); 686 Location right = locs()->in(1);
649 if (right.IsConstant()) { 687 if (right.IsConstant()) {
650 ASSERT(right.constant().IsSmi()); 688 ASSERT(right.constant().IsSmi());
651 const int32_t imm = reinterpret_cast<int32_t>(right.constant().raw()); 689 const int32_t imm = reinterpret_cast<int32_t>(right.constant().raw());
652 __ testl(left, Immediate(imm)); 690 __ testl(left, Immediate(imm));
653 } else { 691 } else {
654 __ testl(left, right.reg()); 692 __ testl(left, right.reg());
655 } 693 }
656 Condition true_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO; 694 Condition true_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO;
657 return true_condition; 695 return true_condition;
658 } 696 }
659 697
660 698
661 void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
662 // Never emitted outside of the BranchInstr.
663 UNREACHABLE();
664 }
665
666
667 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
668 BranchInstr* branch) {
669 BranchLabels labels = compiler->CreateBranchLabels(branch);
670 Condition true_condition = EmitComparisonCode(compiler, labels);
671 EmitBranchOnCondition(compiler, true_condition, labels);
672 }
673
674
675 LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone, 699 LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone,
676 bool opt) const { 700 bool opt) const {
677 const intptr_t kNumInputs = 1; 701 const intptr_t kNumInputs = 1;
678 const intptr_t kNumTemps = 1; 702 const intptr_t kNumTemps = 1;
679 LocationSummary* locs = new (zone) 703 LocationSummary* locs = new (zone)
680 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 704 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
681 locs->set_in(0, Location::RequiresRegister()); 705 locs->set_in(0, Location::RequiresRegister());
682 locs->set_temp(0, Location::RequiresRegister()); 706 locs->set_temp(0, Location::RequiresRegister());
683 locs->set_out(0, Location::RequiresRegister()); 707 locs->set_out(0, Location::RequiresRegister());
684 return locs; 708 return locs;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 // If the cid is not in the list, jump to the opposite label from the cids 740 // If the cid is not in the list, jump to the opposite label from the cids
717 // that are in the list. These must be all the same (see asserts in the 741 // that are in the list. These must be all the same (see asserts in the
718 // constructor). 742 // constructor).
719 Label* target = result ? labels.false_label : labels.true_label; 743 Label* target = result ? labels.false_label : labels.true_label;
720 if (target != labels.fall_through) { 744 if (target != labels.fall_through) {
721 __ jmp(target); 745 __ jmp(target);
722 } 746 }
723 } else { 747 } else {
724 __ jmp(deopt); 748 __ jmp(deopt);
725 } 749 }
726 // Dummy result as the last instruction is a jump, any conditional 750 // Dummy result as this method already did the jump, there's no need
727 // branch using the result will therefore be skipped. 751 // for the caller to branch on a condition.
728 return ZERO; 752 return INVALID_CONDITION;
729 } 753 }
730 754
731 755
732 void TestCidsInstr::EmitBranchCode(FlowGraphCompiler* compiler,
733 BranchInstr* branch) {
734 BranchLabels labels = compiler->CreateBranchLabels(branch);
735 EmitComparisonCode(compiler, labels);
736 }
737
738
739 void TestCidsInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
740 Register result_reg = locs()->out(0).reg();
741 Label is_true, is_false, done;
742 BranchLabels labels = {&is_true, &is_false, &is_false};
743 EmitComparisonCode(compiler, labels);
744 __ Bind(&is_false);
745 __ LoadObject(result_reg, Bool::False());
746 __ jmp(&done, Assembler::kNearJump);
747 __ Bind(&is_true);
748 __ LoadObject(result_reg, Bool::True());
749 __ Bind(&done);
750 }
751
752
753 LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone, 756 LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone,
754 bool opt) const { 757 bool opt) const {
755 const intptr_t kNumInputs = 2; 758 const intptr_t kNumInputs = 2;
756 const intptr_t kNumTemps = 0; 759 const intptr_t kNumTemps = 0;
757 if (operation_cid() == kMintCid) { 760 if (operation_cid() == kMintCid) {
758 const intptr_t kNumTemps = 0; 761 const intptr_t kNumTemps = 0;
759 LocationSummary* locs = new (zone) 762 LocationSummary* locs = new (zone)
760 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 763 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
761 locs->set_in(0, Location::Pair(Location::RequiresRegister(), 764 locs->set_in(0, Location::Pair(Location::RequiresRegister(),
762 Location::RequiresRegister())); 765 Location::RequiresRegister()));
(...skipping 30 matching lines...) Expand all
793 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels); 796 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
794 } else if (operation_cid() == kMintCid) { 797 } else if (operation_cid() == kMintCid) {
795 return EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), labels); 798 return EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), labels);
796 } else { 799 } else {
797 ASSERT(operation_cid() == kDoubleCid); 800 ASSERT(operation_cid() == kDoubleCid);
798 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); 801 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
799 } 802 }
800 } 803 }
801 804
802 805
803 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
804 Label is_true, is_false;
805 BranchLabels labels = {&is_true, &is_false, &is_false};
806 Condition true_condition = EmitComparisonCode(compiler, labels);
807 EmitBranchOnCondition(compiler, true_condition, labels);
808
809 Register result = locs()->out(0).reg();
810 Label done;
811 __ Bind(&is_false);
812 __ LoadObject(result, Bool::False());
813 __ jmp(&done, Assembler::kNearJump);
814 __ Bind(&is_true);
815 __ LoadObject(result, Bool::True());
816 __ Bind(&done);
817 }
818
819
820 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
821 BranchInstr* branch) {
822 BranchLabels labels = compiler->CreateBranchLabels(branch);
823 Condition true_condition = EmitComparisonCode(compiler, labels);
824 EmitBranchOnCondition(compiler, true_condition, labels);
825 }
826
827
828 LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone, 806 LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone,
829 bool opt) const { 807 bool opt) const {
830 return MakeCallSummary(zone); 808 return MakeCallSummary(zone);
831 } 809 }
832 810
833 811
834 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 812 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
835 SetupNative(); 813 SetupNative();
836 Register result = locs()->out(0).reg(); 814 Register result = locs()->out(0).reg();
837 const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function()); 815 const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
(...skipping 3150 matching lines...) Expand 10 before | Expand all | Expand 10 after
3988 __ AddImmediate(ESP, Immediate(kDoubleSize)); 3966 __ AddImmediate(ESP, Immediate(kDoubleSize));
3989 // Mask off sign bit. 3967 // Mask off sign bit.
3990 __ andl(temp, Immediate(0x7FFFFFFF)); 3968 __ andl(temp, Immediate(0x7FFFFFFF));
3991 // Compare with +infinity. 3969 // Compare with +infinity.
3992 __ cmpl(temp, Immediate(0x7FF00000)); 3970 __ cmpl(temp, Immediate(0x7FF00000));
3993 return is_negated ? NOT_EQUAL : EQUAL; 3971 return is_negated ? NOT_EQUAL : EQUAL;
3994 } 3972 }
3995 } 3973 }
3996 3974
3997 3975
3998 void DoubleTestOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
3999 BranchInstr* branch) {
4000 ASSERT(compiler->is_optimizing());
4001 BranchLabels labels = compiler->CreateBranchLabels(branch);
4002 Condition true_condition = EmitComparisonCode(compiler, labels);
4003 EmitBranchOnCondition(compiler, true_condition, labels);
4004 }
4005
4006
4007 void DoubleTestOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4008 Label is_true, is_false;
4009 BranchLabels labels = {&is_true, &is_false, &is_false};
4010 Condition true_condition = EmitComparisonCode(compiler, labels);
4011 EmitBranchOnCondition(compiler, true_condition, labels);
4012
4013 Register result = locs()->out(0).reg();
4014 Label done;
4015 __ Bind(&is_false);
4016 __ LoadObject(result, Bool::False());
4017 __ jmp(&done);
4018 __ Bind(&is_true);
4019 __ LoadObject(result, Bool::True());
4020 __ Bind(&done);
4021 }
4022
4023
4024 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(Zone* zone, 3976 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(Zone* zone,
4025 bool opt) const { 3977 bool opt) const {
4026 const intptr_t kNumInputs = 2; 3978 const intptr_t kNumInputs = 2;
4027 const intptr_t kNumTemps = 0; 3979 const intptr_t kNumTemps = 0;
4028 LocationSummary* summary = new (zone) 3980 LocationSummary* summary = new (zone)
4029 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3981 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4030 summary->set_in(0, Location::RequiresFpuRegister()); 3982 summary->set_in(0, Location::RequiresFpuRegister());
4031 summary->set_in(1, Location::RequiresFpuRegister()); 3983 summary->set_in(1, Location::RequiresFpuRegister());
4032 summary->set_out(0, Location::SameAsFirstInput()); 3984 summary->set_out(0, Location::SameAsFirstInput());
4033 return summary; 3985 return summary;
(...skipping 2676 matching lines...) Expand 10 before | Expand all | Expand 10 after
6710 left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id_); 6662 left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id_);
6711 } 6663 }
6712 if (kind() != Token::kEQ_STRICT) { 6664 if (kind() != Token::kEQ_STRICT) {
6713 ASSERT(kind() == Token::kNE_STRICT); 6665 ASSERT(kind() == Token::kNE_STRICT);
6714 true_condition = NegateCondition(true_condition); 6666 true_condition = NegateCondition(true_condition);
6715 } 6667 }
6716 return true_condition; 6668 return true_condition;
6717 } 6669 }
6718 6670
6719 6671
6720 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6721 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
6722
6723 Label is_true, is_false;
6724 BranchLabels labels = {&is_true, &is_false, &is_false};
6725 Condition true_condition = EmitComparisonCode(compiler, labels);
6726 EmitBranchOnCondition(compiler, true_condition, labels);
6727
6728 Register result = locs()->out(0).reg();
6729 Label done;
6730 __ Bind(&is_false);
6731 __ LoadObject(result, Bool::False());
6732 __ jmp(&done, Assembler::kNearJump);
6733 __ Bind(&is_true);
6734 __ LoadObject(result, Bool::True());
6735 __ Bind(&done);
6736 }
6737
6738
6739 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
6740 BranchInstr* branch) {
6741 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
6742
6743 BranchLabels labels = compiler->CreateBranchLabels(branch);
6744 Condition true_condition = EmitComparisonCode(compiler, labels);
6745 EmitBranchOnCondition(compiler, true_condition, labels);
6746 }
6747
6748
6749 // Detect pattern when one value is zero and another is a power of 2. 6672 // Detect pattern when one value is zero and another is a power of 2.
6750 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { 6673 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) {
6751 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || 6674 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) ||
6752 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); 6675 (Utils::IsPowerOfTwo(v2) && (v1 == 0));
6753 } 6676 }
6754 6677
6755 6678
6756 LocationSummary* IfThenElseInstr::MakeLocationSummary(Zone* zone, 6679 LocationSummary* IfThenElseInstr::MakeLocationSummary(Zone* zone,
6757 bool opt) const { 6680 bool opt) const {
6758 comparison()->InitializeLocationSummary(zone, opt); 6681 comparison()->InitializeLocationSummary(zone, opt);
6759 // TODO(vegorov): support byte register constraints in the register allocator. 6682 // TODO(vegorov): support byte register constraints in the register allocator.
6760 comparison()->locs()->set_out(0, Location::RegisterLocation(EDX)); 6683 comparison()->locs()->set_out(0, Location::RegisterLocation(EDX));
6761 return comparison()->locs(); 6684 return comparison()->locs();
6762 } 6685 }
6763 6686
6764 6687
6765 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6688 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6766 ASSERT(locs()->out(0).reg() == EDX); 6689 ASSERT(locs()->out(0).reg() == EDX);
6767 6690
6768 // Clear upper part of the out register. We are going to use setcc on it 6691 // Clear upper part of the out register. We are going to use setcc on it
6769 // which is a byte move. 6692 // which is a byte move.
6770 __ xorl(EDX, EDX); 6693 __ xorl(EDX, EDX);
6771 6694
6772 // Emit comparison code. This must not overwrite the result register. 6695 // Emit comparison code. This must not overwrite the result register.
6696 // IfThenElseInstr::Supports() should prevent EmitComparisonCode from using
6697 // the labels or returning an invalid condition.
6773 BranchLabels labels = {NULL, NULL, NULL}; 6698 BranchLabels labels = {NULL, NULL, NULL};
6774 Condition true_condition = comparison()->EmitComparisonCode(compiler, labels); 6699 Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
6700 ASSERT(true_condition != INVALID_CONDITION);
6775 6701
6776 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_); 6702 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
6777 6703
6778 intptr_t true_value = if_true_; 6704 intptr_t true_value = if_true_;
6779 intptr_t false_value = if_false_; 6705 intptr_t false_value = if_false_;
6780 6706
6781 if (is_power_of_two_kind) { 6707 if (is_power_of_two_kind) {
6782 if (true_value == 0) { 6708 if (true_value == 0) {
6783 // We need to have zero in EDX on true_condition. 6709 // We need to have zero in EDX on true_condition.
6784 true_condition = NegateCondition(true_condition); 6710 true_condition = NegateCondition(true_condition);
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
6921 __ Drop(1); 6847 __ Drop(1);
6922 __ popl(result); 6848 __ popl(result);
6923 } 6849 }
6924 6850
6925 6851
6926 } // namespace dart 6852 } // namespace dart
6927 6853
6928 #undef __ 6854 #undef __
6929 6855
6930 #endif // defined TARGET_ARCH_IA32 6856 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698