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

Unified Diff: runtime/vm/intermediate_language_x64.cc

Issue 12082063: Enable correct optimized double modulo operation. (TODO: enable remainder optimization). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/intermediate_language_x64.cc
===================================================================
--- runtime/vm/intermediate_language_x64.cc (revision 17815)
+++ runtime/vm/intermediate_language_x64.cc (working copy)
@@ -2421,6 +2421,18 @@
// currently we can't specify these registers because ParallelMoveResolver
// assumes that XMM0 is free at all times.
// TODO(vegorov): allow XMM0 to be used.
+ if (recognized_kind() == MethodRecognizer::kDoubleMod) {
+ ASSERT(InputCount() == 2);
+ const intptr_t kNumTemps = 2;
+ LocationSummary* result =
+ new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall);
+ result->set_in(0, Location::FpuRegisterLocation(XMM1, Location::kDouble));
+ result->set_in(1, Location::FpuRegisterLocation(XMM2, Location::kDouble));
+ result->set_out(Location::FpuRegisterLocation(XMM1, Location::kDouble));
+ result->set_temp(0, Location::FpuRegisterLocation(XMM2, Location::kDouble));
+ result->set_temp(1, Location::FpuRegisterLocation(XMM3, Location::kDouble));
+ return result;
+ }
ASSERT((InputCount() == 1) || (InputCount() == 2));
const intptr_t kNumTemps = 0;
LocationSummary* result =
@@ -2435,6 +2447,12 @@
void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ if (recognized_kind() == MethodRecognizer::kDoubleMod) {
+ // Preserve right argument.
+ __ pushq(RAX);
+ __ movsd(Address(RSP, 0), locs()->in(1).fpu_reg());
+ }
+
ASSERT(locs()->in(0).fpu_reg() == XMM1);
__ EnterFrame(0);
__ ReserveAlignedFrameSpace(0);
@@ -2446,6 +2464,39 @@
__ CallRuntime(TargetFunction());
__ movaps(locs()->out().fpu_reg(), XMM0);
__ leave();
+
+ if (recognized_kind() == MethodRecognizer::kDoubleMod) {
+ // Result of C call is remainder, convert it to modulo.
+ Label done, equal_zero, right_greater_equal_zero;
+ XmmRegister remainder = locs()->out().fpu_reg();
+ XmmRegister zero_temp = locs()->temp(0).fpu_reg();
+ XmmRegister right_temp = locs()->temp(1).fpu_reg();
+
+ __ xorpd(zero_temp, zero_temp); // 0.0 -> 'temp'.
+ __ comisd(remainder, zero_temp);
+ __ j(PARITY_EVEN, &done, Assembler::kNearJump); // NaN -> false;
+ __ j(EQUAL, &equal_zero, Assembler::kNearJump);
+ __ j(ABOVE, &done, Assembler::kNearJump); // (remainder) > 0 -> done.
+ // remainder < 0.
+ // Load preserved right argument.
+ __ movsd(right_temp, Address(RSP, 0));
+ __ comisd(right_temp, zero_temp);
+ __ j(ABOVE_EQUAL, &right_greater_equal_zero, Assembler::kNearJump);
+ // right < 0.
+ __ subsd(remainder, right_temp);
+ __ jmp(&done, Assembler::kNearJump);
+
+ __ Bind(&right_greater_equal_zero);
+ __ addsd(remainder, right_temp);
+ __ jmp(&done);
+
+ __ Bind(&equal_zero);
+ // Switch to the positive 0.0 (just in case it was negative).
+ __ movsd(remainder, zero_temp);
+
+ __ Bind(&done);
+ __ Drop(1); // Remove preserved right argument.
+ }
}
« runtime/vm/intermediate_language.cc ('K') | « runtime/vm/intermediate_language_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698