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

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

Issue 79653002: Merge TRUNCDIV and MOD into one instruction. Icorporated feedback from CL https://codereview.chromi… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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_arm.cc ('k') | runtime/vm/intermediate_language_mips.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) 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/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 3960 matching lines...) Expand 10 before | Expand all | Expand 10 after
3971 } 3971 }
3972 __ Bind(&do_call); 3972 __ Bind(&do_call);
3973 __ CallRuntime(TargetFunction(), InputCount()); 3973 __ CallRuntime(TargetFunction(), InputCount());
3974 __ fstpl(Address(ESP, 0)); 3974 __ fstpl(Address(ESP, 0));
3975 __ movsd(locs()->out().fpu_reg(), Address(ESP, 0)); 3975 __ movsd(locs()->out().fpu_reg(), Address(ESP, 0));
3976 __ Bind(&skip_call); 3976 __ Bind(&skip_call);
3977 __ leave(); 3977 __ leave();
3978 } 3978 }
3979 3979
3980 3980
3981 LocationSummary* MergedMathInstr::MakeLocationSummary() const {
3982 if (kind() == MergedMathInstr::kTruncDivMod) {
3983 const intptr_t kNumInputs = 2;
3984 const intptr_t kNumTemps = 1;
3985 LocationSummary* summary =
3986 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3987 // Both inputs must be writable because they will be untagged.
3988 summary->set_in(0, Location::RegisterLocation(EAX));
3989 summary->set_in(1, Location::WritableRegister());
3990 summary->set_out(Location::RequiresRegister());
3991 // Will be used for sign extension and division.
3992 summary->set_temp(0, Location::RegisterLocation(EDX));
3993 return summary;
3994 }
3995 UNIMPLEMENTED();
3996 return NULL;
3997 }
3998
3999
4000 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4001 Label* deopt = NULL;
4002 if (CanDeoptimize()) {
4003 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp);
4004 }
4005
4006 if (kind() == MergedMathInstr::kTruncDivMod) {
4007 Register left = locs()->in(0).reg();
4008 Register right = locs()->in(1).reg();
4009 Register result = locs()->out().reg();
4010 // Handle divide by zero in runtime.
4011 __ testl(right, right);
4012 __ j(ZERO, deopt);
4013 ASSERT(left == EAX);
4014 ASSERT((right != EDX) && (right != EAX));
4015 ASSERT(locs()->temp(0).reg() == EDX);
4016 ASSERT((result != EDX) && (result != EAX));
4017 __ SmiUntag(left);
4018 __ SmiUntag(right);
4019 __ cdq(); // Sign extend EAX -> EDX:EAX.
4020 __ idivl(right); // EAX: quotient, EDX: remainder.
4021 // Check the corner case of dividing the 'MIN_SMI' with -1, in which
4022 // case we cannot tag the result.
4023 // TODO(srdjan): We could store instead untagged intermediate results in a
4024 // typed array, but then the load indexed instructions would need to be
4025 // able to deoptimize.
4026 __ cmpl(EAX, Immediate(0x40000000));
4027 __ j(EQUAL, deopt);
4028 // Modulo result (EDX) correction:
4029 // res = left % right;
4030 // if (res < 0) {
4031 // if (right < 0) {
4032 // res = res - right;
4033 // } else {
4034 // res = res + right;
4035 // }
4036 // }
4037 Label subtract, done;
4038 __ cmpl(EDX, Immediate(0));
4039 __ j(GREATER_EQUAL, &done, Assembler::kNearJump);
4040 // Result is negative, adjust it.
4041 __ cmpl(right, Immediate(0));
4042 __ j(LESS, &subtract, Assembler::kNearJump);
4043 __ addl(EDX, right);
4044 __ jmp(&done, Assembler::kNearJump);
4045 __ Bind(&subtract);
4046 __ subl(EDX, right);
4047 __ Bind(&done);
4048
4049 __ LoadObject(result, Array::ZoneHandle(Array::New(2, Heap::kOld)));
4050 const intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(kArrayCid);
4051 Address trunc_div_address(
4052 FlowGraphCompiler::ElementAddressForIntIndex(kArrayCid,
4053 index_scale,
4054 result,
4055 0));
4056 Address mod_address(
4057 FlowGraphCompiler::ElementAddressForIntIndex(kArrayCid,
4058 index_scale,
4059 result,
4060 1));
4061 __ SmiTag(EAX);
4062 __ SmiTag(EDX);
4063 __ StoreIntoObjectNoBarrier(result, trunc_div_address, EAX);
4064 __ StoreIntoObjectNoBarrier(result, mod_address, EDX);
4065 return;
4066 }
4067
4068 UNIMPLEMENTED();
4069 }
4070
4071
3981 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { 4072 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const {
3982 return MakeCallSummary(); 4073 return MakeCallSummary();
3983 } 4074 }
3984 4075
3985 4076
3986 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4077 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3987 Label* deopt = compiler->AddDeoptStub(deopt_id(), 4078 Label* deopt = compiler->AddDeoptStub(deopt_id(),
3988 kDeoptPolymorphicInstanceCallTestFail); 4079 kDeoptPolymorphicInstanceCallTestFail);
3989 if (ic_data().NumberOfChecks() == 0) { 4080 if (ic_data().NumberOfChecks() == 0) {
3990 __ jmp(deopt); 4081 __ jmp(deopt);
(...skipping 885 matching lines...) Expand 10 before | Expand all | Expand 10 after
4876 PcDescriptors::kOther, 4967 PcDescriptors::kOther,
4877 locs()); 4968 locs());
4878 __ Drop(2); // Discard type arguments and receiver. 4969 __ Drop(2); // Discard type arguments and receiver.
4879 } 4970 }
4880 4971
4881 } // namespace dart 4972 } // namespace dart
4882 4973
4883 #undef __ 4974 #undef __
4884 4975
4885 #endif // defined TARGET_ARCH_IA32 4976 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698