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}
This commit is contained in:
jochen 2015-11-26 02:11:42 -08:00 committed by Commit bot
parent 05449f741b
commit ed841139df
6 changed files with 5 additions and 118 deletions

View File

@ -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;

View File

@ -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) \

View File

@ -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);

View File

@ -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;

View File

@ -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();

View File

@ -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 __
// -------------------------------------------------------------------------