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:
parent
05449f741b
commit
ed841139df
@ -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 __
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user