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

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

Issue 10453110: Implement optimized unary ops for ia32 as well. Fix a crash in disassembler. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/disassembler_ia32.cc ('k') | runtime/vm/intermediate_language_x64.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) 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 "vm/flow_graph_compiler.h" 10 #include "vm/flow_graph_compiler.h"
11 #include "vm/locations.h" 11 #include "vm/locations.h"
12 #include "vm/object_store.h"
12 #include "vm/stub_code.h" 13 #include "vm/stub_code.h"
13 14
14 #define __ compiler->assembler()-> 15 #define __ compiler->assembler()->
15 16
16 namespace dart { 17 namespace dart {
17 18
18 DECLARE_FLAG(int, optimization_counter_threshold); 19 DECLARE_FLAG(int, optimization_counter_threshold);
19 DECLARE_FLAG(bool, trace_functions); 20 DECLARE_FLAG(bool, trace_functions);
20 21
21 // True iff. the arguments to a call will be properly pushed and can 22 // True iff. the arguments to a call will be properly pushed and can
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 __ pushl(right); 602 __ pushl(right);
602 InstanceCallComp* instance_call_comp = instance_call(); 603 InstanceCallComp* instance_call_comp = instance_call();
603 instance_call_comp->EmitNativeCode(compiler); 604 instance_call_comp->EmitNativeCode(compiler);
604 if (locs()->out().reg() != EAX) { 605 if (locs()->out().reg() != EAX) {
605 __ movl(locs()->out().reg(), EAX); 606 __ movl(locs()->out().reg(), EAX);
606 } 607 }
607 } 608 }
608 609
609 610
610 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const { 611 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const {
611 return NULL; 612 const intptr_t kNumInputs = 1;
613 const intptr_t kNumTemps = 0;
614 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
615 summary->set_in(0, Location::RequiresRegister());
616 summary->set_out(Location::SameAsFirstInput());
617 return summary;
612 } 618 }
613 619
614 620
615 void UnarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compile) { 621 void UnarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
616 UNIMPLEMENTED(); 622 const ICData& ic_data = *instance_call()->ic_data();
623 ASSERT(!ic_data.IsNull());
624 ASSERT(ic_data.num_args_tested() == 1);
625 // TODO(srdjan): Implement for more checks.
626 ASSERT(ic_data.NumberOfChecks() == 1);
627 Class& test_class = Class::Handle();
628 Function& target = Function::Handle();
629 ic_data.GetOneClassCheckAt(0, &test_class, &target);
630
631 Register value = locs()->in(0).reg();
632 Register result = locs()->out().reg();
633 ASSERT(value == result);
634 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(),
635 instance_call()->token_index(),
636 instance_call()->try_index(),
637 kDeoptSmiBinaryOp,
638 value,
639 kNoRegister);
640 if (test_class.id() == kSmi) {
641 __ testl(value, Immediate(kSmiTagMask));
642 __ j(NOT_ZERO, deopt);
643 switch (op_kind()) {
644 case Token::kNEGATE:
645 __ negl(value);
646 __ j(OVERFLOW, deopt);
647 break;
648 case Token::kBIT_NOT:
649 __ notl(value);
650 __ andl(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag.
651 break;
652 default:
653 UNREACHABLE();
654 }
655 } else {
656 UNREACHABLE();
657 }
617 } 658 }
618 659
619 660
620 LocationSummary* NumberNegateComp::MakeLocationSummary() const { 661 LocationSummary* NumberNegateComp::MakeLocationSummary() const {
621 return NULL; 662 const intptr_t kNumInputs = 1;
663 const intptr_t kNumTemps = 1; // Needed for doubles.
664 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
665 summary->set_in(0, Location::RequiresRegister());
666 summary->set_out(Location::SameAsFirstInput());
667 summary->set_temp(0, Location::RequiresRegister());
668 return summary;
622 } 669 }
623 670
624 671
625 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compile) { 672 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) {
626 UNIMPLEMENTED(); 673 const ICData& ic_data = *instance_call()->ic_data();
674 ASSERT(!ic_data.IsNull());
675 ASSERT(ic_data.num_args_tested() == 1);
676
677 // TODO(srdjan): Implement for more checks.
678 ASSERT(ic_data.NumberOfChecks() == 1);
679 Class& test_class = Class::Handle();
680 Function& target = Function::Handle();
681 ic_data.GetOneClassCheckAt(0, &test_class, &target);
682
683 Register value = locs()->in(0).reg();
684 Register result = locs()->out().reg();
685 ASSERT(value == result);
686 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(),
687 instance_call()->token_index(),
688 instance_call()->try_index(),
689 kDeoptSmiBinaryOp,
690 value,
691 kNoRegister);
692 if (test_class.id() == kDouble) {
693 Register temp = locs()->temp(0).reg();
694 ASSERT(result != temp);
695 __ testl(value, Immediate(kSmiTagMask));
696 __ j(ZERO, deopt); // Smi.
697 __ CompareClassId(value, kDouble, temp);
698 __ j(NOT_EQUAL, deopt);
699 // Allocate result object.
700 const Class& double_class =
701 Class::ZoneHandle(Isolate::Current()->object_store()->double_class());
702 const Code& stub =
703 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
704 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
705 __ pushl(value);
706 compiler->GenerateCall(instance_call()->token_index(),
707 instance_call()->try_index(),
708 &label,
709 PcDescriptors::kOther);
710 // Result is in EAX.
711 __ movl(result, EAX);
712 __ popl(temp);
713 __ movsd(XMM0, FieldAddress(temp, Double::value_offset()));
714 __ DoubleNegate(XMM0);
715 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
716 } else {
717 UNREACHABLE();
718 }
627 } 719 }
628 720
629 721
630 } // namespace dart 722 } // namespace dart
631 723
632 #undef __ 724 #undef __
633 725
634 #endif // defined TARGET_ARCH_X64 726 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/disassembler_ia32.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698