Update V8 to version 4.1.0.21
This is a cherry-pick of all commits up to and including the
4.1.0.21 cherry-pick in Chromium.
Original commit message:
Version 4.1.0.21 (cherry-pick)
Merged 206e9136bde0f2b5ae8cb77afbb1e7833e5bd412
Unlink pages from the space page list after evacuation.
BUG=430201
LOG=N
R=jkummerow@chromium.org
Review URL: https://codereview.chromium.org/953813002
Cr-Commit-Position: refs/branch-heads/4.1@{#22}
Cr-Branched-From: 2e08d2a7aa9d65d269d8c57aba82eb38a8cb0a18-refs/heads/candidates@{#25353}
---
FPIIM-449
Change-Id: I8c23c7bbb70772b4858fe8a47b64fa97ee0d1f8c
diff --git a/test/cctest/compiler/test-run-machops.cc b/test/cctest/compiler/test-run-machops.cc
index 985e0f8..974d4ce 100644
--- a/test/cctest/compiler/test-run-machops.cc
+++ b/test/cctest/compiler/test-run-machops.cc
@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <cmath>
#include <functional>
#include <limits>
#include "src/base/bits.h"
-#include "src/compiler/generic-node-inl.h"
+#include "src/codegen.h"
#include "test/cctest/cctest.h"
#include "test/cctest/compiler/codegen-tester.h"
#include "test/cctest/compiler/value-helper.h"
@@ -58,25 +59,25 @@
TEST(CodeGenInt32Binop) {
RawMachineAssemblerTester<void> m;
- const Operator* ops[] = {
+ const Operator* kOps[] = {
m.machine()->Word32And(), m.machine()->Word32Or(),
m.machine()->Word32Xor(), m.machine()->Word32Shl(),
m.machine()->Word32Shr(), m.machine()->Word32Sar(),
m.machine()->Word32Equal(), m.machine()->Int32Add(),
m.machine()->Int32Sub(), m.machine()->Int32Mul(),
- m.machine()->Int32Div(), m.machine()->Int32UDiv(),
- m.machine()->Int32Mod(), m.machine()->Int32UMod(),
+ m.machine()->Int32MulHigh(), m.machine()->Int32Div(),
+ m.machine()->Uint32Div(), m.machine()->Int32Mod(),
+ m.machine()->Uint32Mod(), m.machine()->Uint32MulHigh(),
m.machine()->Int32LessThan(), m.machine()->Int32LessThanOrEqual(),
- m.machine()->Uint32LessThan(), m.machine()->Uint32LessThanOrEqual(),
- NULL};
+ m.machine()->Uint32LessThan(), m.machine()->Uint32LessThanOrEqual()};
- for (int i = 0; ops[i] != NULL; i++) {
+ for (size_t i = 0; i < arraysize(kOps); ++i) {
for (int j = 0; j < 8; j++) {
for (int k = 0; k < 8; k++) {
RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
Node* a = Int32Input(&m, j);
Node* b = Int32Input(&m, k);
- m.Return(m.NewNode(ops[i], a, b));
+ m.Return(m.NewNode(kOps[i], a, b));
m.GenerateCode();
}
}
@@ -127,51 +128,6 @@
}
-TEST(RunRedundantBranch1) {
- RawMachineAssemblerTester<int32_t> m;
- int constant = 944777;
-
- MLabel blocka;
- m.Branch(m.Int32Constant(0), &blocka, &blocka);
- m.Bind(&blocka);
- m.Return(m.Int32Constant(constant));
-
- CHECK_EQ(constant, m.Call());
-}
-
-
-TEST(RunRedundantBranch2) {
- RawMachineAssemblerTester<int32_t> m;
- int constant = 955777;
-
- MLabel blocka, blockb;
- m.Branch(m.Int32Constant(0), &blocka, &blocka);
- m.Bind(&blockb);
- m.Goto(&blocka);
- m.Bind(&blocka);
- m.Return(m.Int32Constant(constant));
-
- CHECK_EQ(constant, m.Call());
-}
-
-
-TEST(RunRedundantBranch3) {
- RawMachineAssemblerTester<int32_t> m;
- int constant = 966777;
-
- MLabel blocka, blockb, blockc;
- m.Branch(m.Int32Constant(0), &blocka, &blockc);
- m.Bind(&blocka);
- m.Branch(m.Int32Constant(0), &blockb, &blockb);
- m.Bind(&blockc);
- m.Goto(&blockb);
- m.Bind(&blockb);
- m.Return(m.Int32Constant(constant));
-
- CHECK_EQ(constant, m.Call());
-}
-
-
TEST(RunDiamond2) {
RawMachineAssemblerTester<int32_t> m;
@@ -571,6 +527,142 @@
}
+TEST(RunInt32AddAndWord32EqualP) {
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
+ m.Return(m.Int32Add(m.Parameter(0),
+ m.Word32Equal(m.Parameter(1), m.Parameter(2))));
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ FOR_INT32_INPUTS(k) {
+ // Use uint32_t because signed overflow is UB in C.
+ int32_t const expected =
+ bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j == *k));
+ CHECK_EQ(expected, m.Call(*i, *j, *k));
+ }
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
+ m.Return(m.Int32Add(m.Word32Equal(m.Parameter(0), m.Parameter(1)),
+ m.Parameter(2)));
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ FOR_INT32_INPUTS(k) {
+ // Use uint32_t because signed overflow is UB in C.
+ int32_t const expected =
+ bit_cast<int32_t>((*i == *j) + bit_cast<uint32_t>(*k));
+ CHECK_EQ(expected, m.Call(*i, *j, *k));
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunInt32AddAndWord32EqualImm) {
+ {
+ FOR_INT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+ m.Return(m.Int32Add(m.Int32Constant(*i),
+ m.Word32Equal(m.Parameter(0), m.Parameter(1))));
+ FOR_INT32_INPUTS(j) {
+ FOR_INT32_INPUTS(k) {
+ // Use uint32_t because signed overflow is UB in C.
+ int32_t const expected =
+ bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j == *k));
+ CHECK_EQ(expected, m.Call(*j, *k));
+ }
+ }
+ }
+ }
+ {
+ FOR_INT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+ m.Return(m.Int32Add(m.Word32Equal(m.Int32Constant(*i), m.Parameter(0)),
+ m.Parameter(1)));
+ FOR_INT32_INPUTS(j) {
+ FOR_INT32_INPUTS(k) {
+ // Use uint32_t because signed overflow is UB in C.
+ int32_t const expected =
+ bit_cast<int32_t>((*i == *j) + bit_cast<uint32_t>(*k));
+ CHECK_EQ(expected, m.Call(*j, *k));
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunInt32AddAndWord32NotEqualP) {
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
+ m.Return(m.Int32Add(m.Parameter(0),
+ m.Word32NotEqual(m.Parameter(1), m.Parameter(2))));
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ FOR_INT32_INPUTS(k) {
+ // Use uint32_t because signed overflow is UB in C.
+ int32_t const expected =
+ bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j != *k));
+ CHECK_EQ(expected, m.Call(*i, *j, *k));
+ }
+ }
+ }
+ }
+ {
+ RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
+ m.Return(m.Int32Add(m.Word32NotEqual(m.Parameter(0), m.Parameter(1)),
+ m.Parameter(2)));
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ FOR_INT32_INPUTS(k) {
+ // Use uint32_t because signed overflow is UB in C.
+ int32_t const expected =
+ bit_cast<int32_t>((*i != *j) + bit_cast<uint32_t>(*k));
+ CHECK_EQ(expected, m.Call(*i, *j, *k));
+ }
+ }
+ }
+ }
+}
+
+
+TEST(RunInt32AddAndWord32NotEqualImm) {
+ {
+ FOR_INT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+ m.Return(m.Int32Add(m.Int32Constant(*i),
+ m.Word32NotEqual(m.Parameter(0), m.Parameter(1))));
+ FOR_INT32_INPUTS(j) {
+ FOR_INT32_INPUTS(k) {
+ // Use uint32_t because signed overflow is UB in C.
+ int32_t const expected =
+ bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j != *k));
+ CHECK_EQ(expected, m.Call(*j, *k));
+ }
+ }
+ }
+ }
+ {
+ FOR_INT32_INPUTS(i) {
+ RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+ m.Return(m.Int32Add(m.Word32NotEqual(m.Int32Constant(*i), m.Parameter(0)),
+ m.Parameter(1)));
+ FOR_INT32_INPUTS(j) {
+ FOR_INT32_INPUTS(k) {
+ // Use uint32_t because signed overflow is UB in C.
+ int32_t const expected =
+ bit_cast<int32_t>((*i != *j) + bit_cast<uint32_t>(*k));
+ CHECK_EQ(expected, m.Call(*j, *k));
+ }
+ }
+ }
+ }
+}
+
+
TEST(RunInt32AddAndWord32SarP) {
{
RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, kMachUint32);
@@ -1233,6 +1325,20 @@
}
+TEST(RunInt32MulHighP) {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Int32MulHigh(bt.param0, bt.param1));
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ int32_t expected = static_cast<int32_t>(
+ (static_cast<int64_t>(*i) * static_cast<int64_t>(*j)) >> 32);
+ CHECK_EQ(expected, bt.call(*i, *j));
+ }
+ }
+}
+
+
TEST(RunInt32MulImm) {
{
FOR_UINT32_INPUTS(i) {
@@ -1259,6 +1365,22 @@
TEST(RunInt32MulAndInt32AddP) {
{
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) {
+ RawMachineAssemblerTester<int32_t> m(kMachInt32);
+ int32_t p0 = *i;
+ int32_t p1 = *j;
+ m.Return(m.Int32Add(m.Int32Constant(p0),
+ m.Int32Mul(m.Parameter(0), m.Int32Constant(p1))));
+ FOR_INT32_INPUTS(k) {
+ int32_t p2 = *k;
+ int expected = p0 + static_cast<int32_t>(p1 * p2);
+ CHECK_EQ(expected, m.Call(p2));
+ }
+ }
+ }
+ }
+ {
RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
m.Return(
m.Int32Add(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
@@ -1347,6 +1469,20 @@
}
+TEST(RunUint32MulHighP) {
+ RawMachineAssemblerTester<int32_t> m;
+ Int32BinopTester bt(&m);
+ bt.AddReturn(m.Uint32MulHigh(bt.param0, bt.param1));
+ FOR_UINT32_INPUTS(i) {
+ FOR_UINT32_INPUTS(j) {
+ int32_t expected = bit_cast<int32_t>(static_cast<uint32_t>(
+ (static_cast<uint64_t>(*i) * static_cast<uint64_t>(*j)) >> 32));
+ CHECK_EQ(expected, bt.call(bit_cast<int32_t>(*i), bit_cast<int32_t>(*j)));
+ }
+ }
+}
+
+
TEST(RunInt32DivP) {
{
RawMachineAssemblerTester<int32_t> m;
@@ -1381,11 +1517,11 @@
}
-TEST(RunInt32UDivP) {
+TEST(RunUint32DivP) {
{
RawMachineAssemblerTester<int32_t> m;
Int32BinopTester bt(&m);
- bt.AddReturn(m.Int32UDiv(bt.param0, bt.param1));
+ bt.AddReturn(m.Uint32Div(bt.param0, bt.param1));
FOR_UINT32_INPUTS(i) {
FOR_UINT32_INPUTS(j) {
uint32_t p0 = *i;
@@ -1400,7 +1536,7 @@
{
RawMachineAssemblerTester<int32_t> m;
Int32BinopTester bt(&m);
- bt.AddReturn(m.Int32Add(bt.param0, m.Int32UDiv(bt.param0, bt.param1)));
+ bt.AddReturn(m.Int32Add(bt.param0, m.Uint32Div(bt.param0, bt.param1)));
FOR_UINT32_INPUTS(i) {
FOR_UINT32_INPUTS(j) {
uint32_t p0 = *i;
@@ -1449,11 +1585,11 @@
}
-TEST(RunInt32UModP) {
+TEST(RunUint32ModP) {
{
RawMachineAssemblerTester<int32_t> m;
Int32BinopTester bt(&m);
- bt.AddReturn(m.Int32UMod(bt.param0, bt.param1));
+ bt.AddReturn(m.Uint32Mod(bt.param0, bt.param1));
FOR_UINT32_INPUTS(i) {
FOR_UINT32_INPUTS(j) {
uint32_t p0 = *i;
@@ -1468,7 +1604,7 @@
{
RawMachineAssemblerTester<int32_t> m;
Int32BinopTester bt(&m);
- bt.AddReturn(m.Int32Add(bt.param0, m.Int32UMod(bt.param0, bt.param1)));
+ bt.AddReturn(m.Int32Add(bt.param0, m.Uint32Mod(bt.param0, bt.param1)));
FOR_UINT32_INPUTS(i) {
FOR_UINT32_INPUTS(j) {
uint32_t p0 = *i;
@@ -2658,22 +2794,23 @@
TEST(RunDeadInt32Binops) {
RawMachineAssemblerTester<int32_t> m;
- const Operator* ops[] = {
- m.machine()->Word32And(), m.machine()->Word32Or(),
- m.machine()->Word32Xor(), m.machine()->Word32Shl(),
- m.machine()->Word32Shr(), m.machine()->Word32Sar(),
- m.machine()->Word32Ror(), m.machine()->Word32Equal(),
- m.machine()->Int32Add(), m.machine()->Int32Sub(),
- m.machine()->Int32Mul(), m.machine()->Int32Div(),
- m.machine()->Int32UDiv(), m.machine()->Int32Mod(),
- m.machine()->Int32UMod(), m.machine()->Int32LessThan(),
- m.machine()->Int32LessThanOrEqual(), m.machine()->Uint32LessThan(),
- m.machine()->Uint32LessThanOrEqual(), NULL};
+ const Operator* kOps[] = {
+ m.machine()->Word32And(), m.machine()->Word32Or(),
+ m.machine()->Word32Xor(), m.machine()->Word32Shl(),
+ m.machine()->Word32Shr(), m.machine()->Word32Sar(),
+ m.machine()->Word32Ror(), m.machine()->Word32Equal(),
+ m.machine()->Int32Add(), m.machine()->Int32Sub(),
+ m.machine()->Int32Mul(), m.machine()->Int32MulHigh(),
+ m.machine()->Int32Div(), m.machine()->Uint32Div(),
+ m.machine()->Int32Mod(), m.machine()->Uint32Mod(),
+ m.machine()->Uint32MulHigh(), m.machine()->Int32LessThan(),
+ m.machine()->Int32LessThanOrEqual(), m.machine()->Uint32LessThan(),
+ m.machine()->Uint32LessThanOrEqual()};
- for (int i = 0; ops[i] != NULL; i++) {
+ for (size_t i = 0; i < arraysize(kOps); ++i) {
RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
- int constant = 0x55555 + i;
- m.NewNode(ops[i], m.Parameter(0), m.Parameter(1));
+ int32_t constant = static_cast<int32_t>(0x55555 + i);
+ m.NewNode(kOps[i], m.Parameter(0), m.Parameter(1));
m.Return(m.Int32Constant(constant));
CHECK_EQ(constant, m.Call(1, 1));
@@ -3102,6 +3239,38 @@
}
+TEST(RunChangeUint32ToFloat64_spilled) {
+ RawMachineAssemblerTester<int32_t> m;
+ const int kNumInputs = 32;
+ int32_t magic = 0x786234;
+ uint32_t input[kNumInputs];
+ double result[kNumInputs];
+ Node* input_node[kNumInputs];
+
+ for (int i = 0; i < kNumInputs; i++) {
+ input_node[i] =
+ m.Load(kMachUint32, m.PointerConstant(&input), m.Int32Constant(i * 4));
+ }
+
+ for (int i = 0; i < kNumInputs; i++) {
+ m.Store(kMachFloat64, m.PointerConstant(&result), m.Int32Constant(i * 8),
+ m.ChangeUint32ToFloat64(input_node[i]));
+ }
+
+ m.Return(m.Int32Constant(magic));
+
+ for (int i = 0; i < kNumInputs; i++) {
+ input[i] = 100 + i;
+ }
+
+ CHECK_EQ(magic, m.Call());
+
+ for (int i = 0; i < kNumInputs; i++) {
+ CHECK_EQ(result[i], static_cast<double>(100 + i));
+ }
+}
+
+
TEST(RunChangeFloat64ToInt32_A) {
RawMachineAssemblerTester<int32_t> m;
int32_t magic = 0x786234;
@@ -3272,6 +3441,38 @@
}
+TEST(RunTruncateFloat64ToFloat32_spilled) {
+ RawMachineAssemblerTester<uint32_t> m;
+ const int kNumInputs = 32;
+ int32_t magic = 0x786234;
+ double input[kNumInputs];
+ float result[kNumInputs];
+ Node* input_node[kNumInputs];
+
+ for (int i = 0; i < kNumInputs; i++) {
+ input_node[i] =
+ m.Load(kMachFloat64, m.PointerConstant(&input), m.Int32Constant(i * 8));
+ }
+
+ for (int i = 0; i < kNumInputs; i++) {
+ m.Store(kMachFloat32, m.PointerConstant(&result), m.Int32Constant(i * 4),
+ m.TruncateFloat64ToFloat32(input_node[i]));
+ }
+
+ m.Return(m.Int32Constant(magic));
+
+ for (int i = 0; i < kNumInputs; i++) {
+ input[i] = 0.1 + i;
+ }
+
+ CHECK_EQ(magic, m.Call());
+
+ for (int i = 0; i < kNumInputs; i++) {
+ CHECK_EQ(result[i], DoubleToFloat32(input[i]));
+ }
+}
+
+
TEST(RunDeadChangeFloat64ToInt32) {
RawMachineAssemblerTester<int32_t> m;
const int magic = 0x88abcda4;
@@ -4242,4 +4443,249 @@
}
}
+
+TEST(RunChangeFloat32ToFloat64) {
+ double actual = 0.0f;
+ float expected = 0.0;
+ RawMachineAssemblerTester<int32_t> m;
+ m.StoreToPointer(
+ &actual, kMachFloat64,
+ m.ChangeFloat32ToFloat64(m.LoadFromPointer(&expected, kMachFloat32)));
+ m.Return(m.Int32Constant(0));
+ FOR_FLOAT32_INPUTS(i) {
+ expected = *i;
+ CHECK_EQ(0, m.Call());
+ CHECK_EQ(expected, actual);
+ }
+}
+
+
+TEST(RunChangeFloat32ToFloat64_spilled) {
+ RawMachineAssemblerTester<int32_t> m;
+ const int kNumInputs = 32;
+ int32_t magic = 0x786234;
+ float input[kNumInputs];
+ double result[kNumInputs];
+ Node* input_node[kNumInputs];
+
+ for (int i = 0; i < kNumInputs; i++) {
+ input_node[i] =
+ m.Load(kMachFloat32, m.PointerConstant(&input), m.Int32Constant(i * 4));
+ }
+
+ for (int i = 0; i < kNumInputs; i++) {
+ m.Store(kMachFloat64, m.PointerConstant(&result), m.Int32Constant(i * 8),
+ m.ChangeFloat32ToFloat64(input_node[i]));
+ }
+
+ m.Return(m.Int32Constant(magic));
+
+ for (int i = 0; i < kNumInputs; i++) {
+ input[i] = 100.9f + i;
+ }
+
+ CHECK_EQ(magic, m.Call());
+
+ for (int i = 0; i < kNumInputs; i++) {
+ CHECK_EQ(result[i], static_cast<double>(input[i]));
+ }
+}
+
+
+TEST(RunTruncateFloat64ToFloat32) {
+ float actual = 0.0f;
+ double input = 0.0;
+ RawMachineAssemblerTester<int32_t> m;
+ m.StoreToPointer(
+ &actual, kMachFloat32,
+ m.TruncateFloat64ToFloat32(m.LoadFromPointer(&input, kMachFloat64)));
+ m.Return(m.Int32Constant(0));
+ FOR_FLOAT64_INPUTS(i) {
+ input = *i;
+ volatile double expected = DoubleToFloat32(input);
+ CHECK_EQ(0, m.Call());
+ CHECK_EQ(expected, actual);
+ }
+}
+
+
+TEST(RunFloat32Constant) {
+ FOR_FLOAT32_INPUTS(i) {
+ float expected = *i;
+ float actual = *i;
+ RawMachineAssemblerTester<int32_t> m;
+ m.StoreToPointer(&actual, kMachFloat32, m.Float32Constant(expected));
+ m.Return(m.Int32Constant(0));
+ CHECK_EQ(0, m.Call());
+ CHECK_EQ(expected, actual);
+ }
+}
+
+
+static double two_30 = 1 << 30; // 2^30 is a smi boundary.
+static double two_52 = two_30 * (1 << 22); // 2^52 is a precision boundary.
+static double kValues[] = {0.1,
+ 0.2,
+ 0.49999999999999994,
+ 0.5,
+ 0.7,
+ 1.0 - std::numeric_limits<double>::epsilon(),
+ -0.1,
+ -0.49999999999999994,
+ -0.5,
+ -0.7,
+ 1.1,
+ 1.0 + std::numeric_limits<double>::epsilon(),
+ 1.5,
+ 1.7,
+ -1,
+ -1 + std::numeric_limits<double>::epsilon(),
+ -1 - std::numeric_limits<double>::epsilon(),
+ -1.1,
+ -1.5,
+ -1.7,
+ std::numeric_limits<double>::min(),
+ -std::numeric_limits<double>::min(),
+ std::numeric_limits<double>::max(),
+ -std::numeric_limits<double>::max(),
+ std::numeric_limits<double>::infinity(),
+ -std::numeric_limits<double>::infinity(),
+ two_30,
+ two_30 + 0.1,
+ two_30 + 0.5,
+ two_30 + 0.7,
+ two_30 - 1,
+ two_30 - 1 + 0.1,
+ two_30 - 1 + 0.5,
+ two_30 - 1 + 0.7,
+ -two_30,
+ -two_30 + 0.1,
+ -two_30 + 0.5,
+ -two_30 + 0.7,
+ -two_30 + 1,
+ -two_30 + 1 + 0.1,
+ -two_30 + 1 + 0.5,
+ -two_30 + 1 + 0.7,
+ two_52,
+ two_52 + 0.1,
+ two_52 + 0.5,
+ two_52 + 0.5,
+ two_52 + 0.7,
+ two_52 + 0.7,
+ two_52 - 1,
+ two_52 - 1 + 0.1,
+ two_52 - 1 + 0.5,
+ two_52 - 1 + 0.7,
+ -two_52,
+ -two_52 + 0.1,
+ -two_52 + 0.5,
+ -two_52 + 0.7,
+ -two_52 + 1,
+ -two_52 + 1 + 0.1,
+ -two_52 + 1 + 0.5,
+ -two_52 + 1 + 0.7,
+ two_30,
+ two_30 - 0.1,
+ two_30 - 0.5,
+ two_30 - 0.7,
+ two_30 - 1,
+ two_30 - 1 - 0.1,
+ two_30 - 1 - 0.5,
+ two_30 - 1 - 0.7,
+ -two_30,
+ -two_30 - 0.1,
+ -two_30 - 0.5,
+ -two_30 - 0.7,
+ -two_30 + 1,
+ -two_30 + 1 - 0.1,
+ -two_30 + 1 - 0.5,
+ -two_30 + 1 - 0.7,
+ two_52,
+ two_52 - 0.1,
+ two_52 - 0.5,
+ two_52 - 0.5,
+ two_52 - 0.7,
+ two_52 - 0.7,
+ two_52 - 1,
+ two_52 - 1 - 0.1,
+ two_52 - 1 - 0.5,
+ two_52 - 1 - 0.7,
+ -two_52,
+ -two_52 - 0.1,
+ -two_52 - 0.5,
+ -two_52 - 0.7,
+ -two_52 + 1,
+ -two_52 + 1 - 0.1,
+ -two_52 + 1 - 0.5,
+ -two_52 + 1 - 0.7};
+
+
+TEST(RunFloat64Floor) {
+ double input = -1.0;
+ double result = 0.0;
+ RawMachineAssemblerTester<int32_t> m;
+ if (!m.machine()->HasFloat64Floor()) return;
+ m.StoreToPointer(&result, kMachFloat64,
+ m.Float64Floor(m.LoadFromPointer(&input, kMachFloat64)));
+ m.Return(m.Int32Constant(0));
+ for (size_t i = 0; i < arraysize(kValues); ++i) {
+ input = kValues[i];
+ CHECK_EQ(0, m.Call());
+ double expected = std::floor(kValues[i]);
+ CHECK_EQ(expected, result);
+ }
+}
+
+
+TEST(RunFloat64Ceil) {
+ double input = -1.0;
+ double result = 0.0;
+ RawMachineAssemblerTester<int32_t> m;
+ if (!m.machine()->HasFloat64Ceil()) return;
+ m.StoreToPointer(&result, kMachFloat64,
+ m.Float64Ceil(m.LoadFromPointer(&input, kMachFloat64)));
+ m.Return(m.Int32Constant(0));
+ for (size_t i = 0; i < arraysize(kValues); ++i) {
+ input = kValues[i];
+ CHECK_EQ(0, m.Call());
+ double expected = std::ceil(kValues[i]);
+ CHECK_EQ(expected, result);
+ }
+}
+
+
+TEST(RunFloat64RoundTruncate) {
+ double input = -1.0;
+ double result = 0.0;
+ RawMachineAssemblerTester<int32_t> m;
+ if (!m.machine()->HasFloat64Ceil()) return;
+ m.StoreToPointer(
+ &result, kMachFloat64,
+ m.Float64RoundTruncate(m.LoadFromPointer(&input, kMachFloat64)));
+ m.Return(m.Int32Constant(0));
+ for (size_t i = 0; i < arraysize(kValues); ++i) {
+ input = kValues[i];
+ CHECK_EQ(0, m.Call());
+ double expected = trunc(kValues[i]);
+ CHECK_EQ(expected, result);
+ }
+}
+
+
+TEST(RunFloat64RoundTiesAway) {
+ double input = -1.0;
+ double result = 0.0;
+ RawMachineAssemblerTester<int32_t> m;
+ if (!m.machine()->HasFloat64RoundTiesAway()) return;
+ m.StoreToPointer(
+ &result, kMachFloat64,
+ m.Float64RoundTiesAway(m.LoadFromPointer(&input, kMachFloat64)));
+ m.Return(m.Int32Constant(0));
+ for (size_t i = 0; i < arraysize(kValues); ++i) {
+ input = kValues[i];
+ CHECK_EQ(0, m.Call());
+ double expected = round(kValues[i]);
+ CHECK_EQ(expected, result);
+ }
+}
#endif // V8_TURBOFAN_TARGET