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

Unified Diff: runtime/vm/intermediate_language_ia32.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_ia32.cc
===================================================================
--- runtime/vm/intermediate_language_ia32.cc (revision 17815)
+++ runtime/vm/intermediate_language_ia32.cc (working copy)
@@ -2551,6 +2551,18 @@
LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const {
+ 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 =
@@ -2565,6 +2577,13 @@
void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ if (recognized_kind() == MethodRecognizer::kDoubleMod) {
+ // Preserve right argument.
+ __ pushl(EAX);
+ __ pushl(EAX);
+ __ movsd(Address(ESP, 0), locs()->in(1).fpu_reg());
+ }
+
__ EnterFrame(0);
__ ReserveAlignedFrameSpace(kDoubleSize * InputCount());
for (intptr_t i = 0; i < InputCount(); i++) {
@@ -2574,6 +2593,39 @@
__ fstpl(Address(ESP, 0));
__ movsd(locs()->out().fpu_reg(), Address(ESP, 0));
__ 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(ESP, 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(2); // Remove preserved right argument.
+ }
}

Powered by Google App Engine
This is Rietveld 408576698