Commit 9b88818c authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[utils] Move modulo from codegen to utils

This also changes modulo to be more like others, e.g., Pow:
- have an inline Modulo
- have a modulo_double_double that we can use as FUNCTION_ADDR in assembler.cc

Bug: 
Change-Id: Id360e4adcde5712ffc5ac22abd3bbaab6aec09f5
Reviewed-on: https://chromium-review.googlesource.com/728027
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48747}
parent 9c6f328b
......@@ -1006,7 +1006,7 @@ ExternalReference ExternalReference::wasm_clear_thread_in_wasm_flag(
static void f64_mod_wrapper(double* param0, double* param1) {
WriteDoubleValue(param0,
modulo(ReadDoubleValue(param0), ReadDoubleValue(param1)));
Modulo(ReadDoubleValue(param0), ReadDoubleValue(param1)));
}
ExternalReference ExternalReference::f64_mod_wrapper_function(
......@@ -1507,6 +1507,8 @@ double power_double_double(double x, double y) {
return Pow(x, y);
}
double modulo_double_double(double x, double y) { return Modulo(x, y); }
ExternalReference ExternalReference::power_double_double_function(
Isolate* isolate) {
return ExternalReference(Redirect(isolate,
......@@ -1516,9 +1518,8 @@ ExternalReference ExternalReference::power_double_double_function(
ExternalReference ExternalReference::mod_two_doubles_operation(
Isolate* isolate) {
return ExternalReference(Redirect(isolate,
FUNCTION_ADDR(modulo),
BUILTIN_FP_FP_CALL));
return ExternalReference(Redirect(
isolate, FUNCTION_ADDR(modulo_double_double), BUILTIN_FP_FP_CALL));
}
ExternalReference ExternalReference::debug_last_step_action_address(
......
......@@ -4,10 +4,6 @@
#include "src/codegen.h"
#if defined(V8_OS_AIX)
#include <fenv.h> // NOLINT(build/c++11)
#endif
#include <memory>
#include "src/bootstrapper.h"
......@@ -21,33 +17,6 @@ namespace v8 {
namespace internal {
#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
// dividend is a zero and divisor is nonzero finite => result equals dividend
if (!(std::isfinite(x) && (!std::isfinite(y) && !std::isnan(y))) &&
!(x == 0 && (y != 0 && std::isfinite(y)))) {
x = fmod(x, y);
}
return x;
}
#else // POSIX
double modulo(double x, double y) {
#if defined(V8_OS_AIX)
// AIX raises an underflow exception for (Number.MIN_VALUE % Number.MAX_VALUE)
feclearexcept(FE_ALL_EXCEPT);
double result = std::fmod(x, y);
int exception = fetestexcept(FE_UNDERFLOW);
return (exception ? x : result);
#else
return std::fmod(x, y);
#endif
}
#endif // defined(V8_OS_WIN)
#define UNARY_MATH_FUNCTION(name, generator) \
static UnaryMathFunctionWithIsolate fast_##name##_function = nullptr; \
double std_##name(double x, Isolate* isolate) { return std::name(x); } \
......
......@@ -29,8 +29,6 @@ typedef double (*UnaryMathFunctionWithIsolate)(double x, Isolate* isolate);
UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate);
V8_EXPORT_PRIVATE double modulo(double x, double y);
// Custom implementation of math functions.
double fast_sqrt(double input, Isolate* isolate);
void lazily_initialize_fast_sqrt(Isolate* isolate);
......
......@@ -465,7 +465,7 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
return Replace(m.left().node());
}
if (m.IsFoldable()) { // K % K => K
return ReplaceFloat64(modulo(m.left().Value(), m.right().Value()));
return ReplaceFloat64(Modulo(m.left().Value(), m.right().Value()));
}
break;
}
......
......@@ -1263,7 +1263,7 @@ char* DoubleToRadixCString(double value, int radix) {
buffer[--integer_cursor] = '0';
}
do {
double remainder = modulo(integer, radix);
double remainder = Modulo(integer, radix);
buffer[--integer_cursor] = chars[static_cast<int>(remainder)];
integer = (integer - remainder) / radix;
} while (integer > 0);
......
......@@ -689,7 +689,7 @@ MaybeHandle<Object> Object::Modulus(Isolate* isolate, Handle<Object> lhs,
ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object);
ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object);
}
return isolate->factory()->NewNumber(modulo(lhs->Number(), rhs->Number()));
return isolate->factory()->NewNumber(Modulo(lhs->Number(), rhs->Number()));
}
......
......@@ -14,7 +14,6 @@
namespace v8 {
namespace internal {
SimpleStringBuilder::SimpleStringBuilder(int size) {
buffer_ = Vector<char>::New(size);
position_ = 0;
......
......@@ -5,6 +5,9 @@
#ifndef V8_UTILS_H_
#define V8_UTILS_H_
#if defined(V8_OS_AIX)
#include <fenv.h> // NOLINT(build/c++11)
#endif
#include <limits.h>
#include <stdlib.h>
#include <string.h>
......@@ -210,6 +213,27 @@ inline double Floor(double x) {
return std::floor(x);
}
inline double Modulo(double x, double y) {
#if defined(V8_OS_WIN)
// Workaround MS fmod bugs. ECMA-262 says:
// dividend is finite and divisor is an infinity => result equals dividend
// dividend is a zero and divisor is nonzero finite => result equals dividend
if (!(std::isfinite(x) && (!std::isfinite(y) && !std::isnan(y))) &&
!(x == 0 && (y != 0 && std::isfinite(y)))) {
x = fmod(x, y);
}
return x;
#elif defined(V8_OS_AIX)
// AIX raises an underflow exception for (Number.MIN_VALUE % Number.MAX_VALUE)
feclearexcept(FE_ALL_EXCEPT);
double result = std::fmod(x, y);
int exception = fetestexcept(FE_UNDERFLOW);
return (exception ? x : result);
#else
return std::fmod(x, y);
#endif
}
inline double Pow(double x, double y) {
if (y == 0.0) return 1.0;
if (std::isnan(y) || ((x == 1 || x == -1) && std::isinf(y))) {
......
......@@ -3690,7 +3690,7 @@ TEST(RunFloat64Mod) {
m.Return(m.Float64Mod(m.Parameter(0), m.Parameter(1)));
FOR_FLOAT64_INPUTS(i) {
FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(modulo(*i, *j), m.Call(*i, *j)); }
FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(Modulo(*i, *j), m.Call(*i, *j)); }
}
}
......@@ -4034,7 +4034,7 @@ TEST(RunFloat64ModP) {
bt.AddReturn(m.Float64Mod(bt.param0, bt.param1));
FOR_FLOAT64_INPUTS(i) {
FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(modulo(*i, *j), bt.call(*i, *j)); }
FOR_FLOAT64_INPUTS(j) { CHECK_DOUBLE_EQ(Modulo(*i, *j), bt.call(*i, *j)); }
}
}
......
......@@ -302,6 +302,7 @@ int32_t shift_right(int32_t x, int32_t y) { return x >> (y & 0x1f); }
int32_t bit_or(int32_t x, int32_t y) { return x | y; }
int32_t bit_and(int32_t x, int32_t y) { return x & y; }
int32_t bit_xor(int32_t x, int32_t y) { return x ^ y; }
double modulo_double_double(double x, double y) { return Modulo(x, y); }
} // namespace
......@@ -329,7 +330,7 @@ TEST_F(TyperTest, TypeJSDivide) {
}
TEST_F(TyperTest, TypeJSModulus) {
TestBinaryArithOp(javascript_.Modulus(), modulo);
TestBinaryArithOp(javascript_.Modulus(), modulo_double_double);
}
TEST_F(TyperTest, TypeJSBitwiseOr) {
......
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