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

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
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 560 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 __ pushl(right); 583 __ pushl(right);
583 InstanceCallComp* instance_call_comp = instance_call(); 584 InstanceCallComp* instance_call_comp = instance_call();
584 instance_call_comp->EmitNativeCode(compiler); 585 instance_call_comp->EmitNativeCode(compiler);
585 if (locs()->out().reg() != EAX) { 586 if (locs()->out().reg() != EAX) {
586 __ movl(locs()->out().reg(), EAX); 587 __ movl(locs()->out().reg(), EAX);
587 } 588 }
588 } 589 }
589 590
590 591
591 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const { 592 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const {
592 return NULL; 593 const intptr_t kNumInputs = 1;
594 const intptr_t kNumTemps = 0;
595 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
596 summary->set_in(0, Location::RequiresRegister());
597 summary->set_out(Location::SameAsFirstInput());
598 return summary;
593 } 599 }
594 600
595 601
596 void UnarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compile) { 602 void UnarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
597 UNIMPLEMENTED(); 603 const ICData& ic_data = *instance_call()->ic_data();
604 ASSERT(!ic_data.IsNull());
605 ASSERT(ic_data.num_args_tested() == 1);
606 // TODO(srdjan): Implement for more checks.
607 ASSERT(ic_data.NumberOfChecks() == 1);
608 Class& test_class = Class::Handle();
609 Function& target = Function::Handle();
610 ic_data.GetOneClassCheckAt(0, &test_class, &target);
611
612 Register value = locs()->in(0).reg();
613 Register result = locs()->out().reg();
614 ASSERT(value == result);
615 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(),
616 instance_call()->token_index(),
617 instance_call()->try_index(),
618 kDeoptSmiBinaryOp,
619 value,
620 kNoRegister);
621 if (test_class.id() == kSmi) {
622 __ testl(value, Immediate(kSmiTagMask));
623 __ j(NOT_ZERO, deopt);
624 switch (op_kind()) {
625 case Token::kNEGATE:
626 __ negl(value);
627 __ j(OVERFLOW, deopt);
628 break;
629 case Token::kBIT_NOT:
630 __ notl(value);
631 __ andl(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag.
632 break;
633 default:
634 UNREACHABLE();
635 }
636 } else {
637 UNREACHABLE();
638 }
598 } 639 }
599 640
600 641
601 LocationSummary* NumberNegateComp::MakeLocationSummary() const { 642 LocationSummary* NumberNegateComp::MakeLocationSummary() const {
602 return NULL; 643 const intptr_t kNumInputs = 1;
644 const intptr_t kNumTemps = 1; // Needed for doubles.
645 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
646 summary->set_in(0, Location::RequiresRegister());
647 summary->set_out(Location::SameAsFirstInput());
648 summary->set_temp(0, Location::RequiresRegister());
649 return summary;
603 } 650 }
604 651
605 652
606 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compile) { 653 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) {
607 UNIMPLEMENTED(); 654 const ICData& ic_data = *instance_call()->ic_data();
655 ASSERT(!ic_data.IsNull());
656 ASSERT(ic_data.num_args_tested() == 1);
657
658 // TODO(srdjan): Implement for more checks.
659 ASSERT(ic_data.NumberOfChecks() == 1);
660 Class& test_class = Class::Handle();
661 Function& target = Function::Handle();
662 ic_data.GetOneClassCheckAt(0, &test_class, &target);
663
664 Register value = locs()->in(0).reg();
665 Register result = locs()->out().reg();
666 ASSERT(value == result);
667 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(),
668 instance_call()->token_index(),
669 instance_call()->try_index(),
670 kDeoptSmiBinaryOp,
671 value,
672 kNoRegister);
673 if (test_class.id() == kDouble) {
674 Register temp = locs()->temp(0).reg();
675 ASSERT(result != temp);
676 __ testl(value, Immediate(kSmiTagMask));
677 __ j(ZERO, deopt); // Smi.
678 __ CompareClassId(value, kDouble, temp);
679 __ j(NOT_EQUAL, deopt);
680 // Allocate result object.
681 const Class& double_class =
682 Class::ZoneHandle(Isolate::Current()->object_store()->double_class());
683 const Code& stub =
684 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
685 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
686 __ pushl(value);
687 compiler->GenerateCall(instance_call()->token_index(),
688 instance_call()->try_index(),
689 &label,
690 PcDescriptors::kOther);
691 // Result is in EAX.
692 __ movl(result, EAX);
Florian Schneider 2012/06/01 15:49:10 You could avoid the mov if result is already EAX.
srdjan 2012/06/01 18:27:25 Unless preformance/code-size is hurt, I'd like to
Florian Schneider 2012/06/02 18:54:11 Ok, I meant more along this here without changing
693 __ popl(temp);
694 __ movsd(XMM0, FieldAddress(temp, Double::value_offset()));
695 __ DoubleNegate(XMM0);
696 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
697 } else {
698 UNREACHABLE();
699 }
608 } 700 }
609 701
610 702
611 } // namespace dart 703 } // namespace dart
612 704
613 #undef __ 705 #undef __
614 706
615 #endif // defined TARGET_ARCH_X64 707 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698