Commit ed841139 authored by jochen's avatar jochen Committed by Commit bot

Remove custom win64 modulo code

Just use the same workaround as on win32.

Also replace fmod calls with modulo() for consistency

BUG=none
R=yangguo@chromium.org
LOG=n

Review URL: https://codereview.chromium.org/1479773002

Cr-Commit-Position: refs/heads/master@{#32322}
parent 05449f74
......@@ -2759,7 +2759,7 @@ double Simulator::FPRoundInt(double value, FPRounding round_mode) {
// If the error is greater than 0.5, or is equal to 0.5 and the integer
// result is odd, round up.
} else if ((error > 0.5) ||
((error == 0.5) && (fmod(int_result, 2) != 0))) {
((error == 0.5) && (modulo(int_result, 2) != 0))) {
int_result++;
}
break;
......
......@@ -20,24 +20,7 @@ namespace v8 {
namespace internal {
#if defined(_WIN64)
typedef double (*ModuloFunction)(double, double);
static ModuloFunction modulo_function = NULL;
// Defined in codegen-x64.cc.
ModuloFunction CreateModuloFunction();
void init_modulo_function() {
modulo_function = CreateModuloFunction();
}
double modulo(double x, double y) {
// Note: here we rely on dependent reads being ordered. This is true
// on all architectures we currently support.
return (*modulo_function)(x, y);
}
#elif defined(_WIN32)
#if defined(V8_OS_WIN)
double modulo(double x, double y) {
// Workaround MS fmod bugs. ECMA-262 says:
// dividend is finite and divisor is an infinity => result equals dividend
......@@ -61,7 +44,7 @@ double modulo(double x, double y) {
return std::fmod(x, y);
#endif
}
#endif // defined(_WIN64)
#endif // defined(V8_OS_WIN)
#define UNARY_MATH_FUNCTION(name, generator) \
......
......@@ -100,9 +100,6 @@ double modulo(double x, double y);
// Custom implementation of math functions.
double fast_exp(double input, Isolate* isolate);
double fast_sqrt(double input, Isolate* isolate);
#ifdef _WIN64
void init_modulo_function();
#endif
void lazily_initialize_fast_exp(Isolate* isolate);
void lazily_initialize_fast_sqrt(Isolate* isolate);
......
......@@ -10,6 +10,7 @@
#include "src/assert-scope.h"
#include "src/char-predicates-inl.h"
#include "src/codegen.h"
#include "src/conversions-inl.h"
#include "src/dtoa.h"
#include "src/factory.h"
......@@ -440,7 +441,7 @@ char* DoubleToRadixCString(double value, int radix) {
// at least one digit.
int integer_pos = kBufferSize - 2;
do {
double remainder = std::fmod(integer_part, radix);
double remainder = modulo(integer_part, radix);
integer_buffer[integer_pos--] = chars[static_cast<int>(remainder)];
integer_part -= remainder;
integer_part /= radix;
......
......@@ -80,9 +80,6 @@ void V8::InitializeOncePerProcessImpl() {
Sampler::SetUp();
CpuFeatures::Probe(false);
init_memcopy_functions();
#ifdef _WIN64
init_modulo_function();
#endif
ElementsAccessor::InitializeOncePerProcess();
LOperand::SetUpCaches();
SetUpJSCallerSavedCodeData();
......
......@@ -87,97 +87,6 @@ UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) {
return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer);
}
#ifdef _WIN64
typedef double (*ModuloFunction)(double, double);
// Define custom fmod implementation.
ModuloFunction CreateModuloFunction() {
size_t actual_size;
byte* buffer = static_cast<byte*>(
base::OS::Allocate(Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size),
CodeObjectRequired::kNo);
// Generated code is put into a fixed, unmovable, buffer, and not into
// the V8 heap. We can't, and don't, refer to any relocatable addresses
// (e.g. the JavaScript nan-object).
// Windows 64 ABI passes double arguments in xmm0, xmm1 and
// returns result in xmm0.
// Argument backing space is allocated on the stack above
// the return address.
// Compute x mod y.
// Load y and x (use argument backing store as temporary storage).
__ Movsd(Operand(rsp, kRegisterSize * 2), xmm1);
__ Movsd(Operand(rsp, kRegisterSize), xmm0);
__ fld_d(Operand(rsp, kRegisterSize * 2));
__ fld_d(Operand(rsp, kRegisterSize));
// Clear exception flags before operation.
{
Label no_exceptions;
__ fwait();
__ fnstsw_ax();
// Clear if Illegal Operand or Zero Division exceptions are set.
__ testb(rax, Immediate(5));
__ j(zero, &no_exceptions);
__ fnclex();
__ bind(&no_exceptions);
}
// Compute st(0) % st(1)
{
Label partial_remainder_loop;
__ bind(&partial_remainder_loop);
__ fprem();
__ fwait();
__ fnstsw_ax();
__ testl(rax, Immediate(0x400 /* C2 */));
// If C2 is set, computation only has partial result. Loop to
// continue computation.
__ j(not_zero, &partial_remainder_loop);
}
Label valid_result;
Label return_result;
// If Invalid Operand or Zero Division exceptions are set,
// return NaN.
__ testb(rax, Immediate(5));
__ j(zero, &valid_result);
__ fstp(0); // Drop result in st(0).
int64_t kNaNValue = V8_INT64_C(0x7ff8000000000000);
__ movq(rcx, kNaNValue);
__ movq(Operand(rsp, kRegisterSize), rcx);
__ Movsd(xmm0, Operand(rsp, kRegisterSize));
__ jmp(&return_result);
// If result is valid, return that.
__ bind(&valid_result);
__ fstp_d(Operand(rsp, kRegisterSize));
__ Movsd(xmm0, Operand(rsp, kRegisterSize));
// Clean up FPU stack and exceptions and return xmm0
__ bind(&return_result);
__ fstp(0); // Unload y.
Label clear_exceptions;
__ testb(rax, Immediate(0x3f /* Any Exception*/));
__ j(not_zero, &clear_exceptions);
__ ret(0);
__ bind(&clear_exceptions);
__ fnclex();
__ ret(0);
CodeDesc desc;
masm.GetCode(&desc);
base::OS::ProtectCode(buffer, actual_size);
// Call the function from C++ through this pointer.
return FUNCTION_CAST<ModuloFunction>(buffer);
}
#endif
#undef __
// -------------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment