Commit 0794c3c9 authored by ahaas's avatar ahaas Committed by Commit bot

[turbofan] Fixed the second return value of TryTruncateFloatXXToUint64.

As required by the spec, the second return value now returns success
also for the range between 0 and -1 where the conversion results in 0.

R=bradnelson@chromium.org, mstarzinger@chromium.org, v8-arm-ports@googlegroups.com, v8-mips-ports@googlegroups.com

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

Cr-Commit-Position: refs/heads/master@{#32936}
parent fe484ff6
...@@ -1070,16 +1070,16 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { ...@@ -1070,16 +1070,16 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
case kArm64Float32ToUint64: case kArm64Float32ToUint64:
__ Fcvtzu(i.OutputRegister64(), i.InputFloat32Register(0)); __ Fcvtzu(i.OutputRegister64(), i.InputFloat32Register(0));
if (i.OutputCount() > 1) { if (i.OutputCount() > 1) {
__ Fcmp(i.InputFloat32Register(0), 0.0); __ Fcmp(i.InputFloat32Register(0), -1.0);
__ Ccmp(i.OutputRegister(0), -1, ZFlag, ge); __ Ccmp(i.OutputRegister(0), -1, ZFlag, gt);
__ Cset(i.OutputRegister(1), ne); __ Cset(i.OutputRegister(1), ne);
} }
break; break;
case kArm64Float64ToUint64: case kArm64Float64ToUint64:
__ Fcvtzu(i.OutputRegister64(), i.InputDoubleRegister(0)); __ Fcvtzu(i.OutputRegister64(), i.InputDoubleRegister(0));
if (i.OutputCount() > 1) { if (i.OutputCount() > 1) {
__ Fcmp(i.InputDoubleRegister(0), 0.0); __ Fcmp(i.InputDoubleRegister(0), -1.0);
__ Ccmp(i.OutputRegister(0), -1, ZFlag, ge); __ Ccmp(i.OutputRegister(0), -1, ZFlag, gt);
__ Cset(i.OutputRegister(1), ne); __ Cset(i.OutputRegister(1), ne);
} }
break; break;
......
...@@ -1109,14 +1109,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { ...@@ -1109,14 +1109,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
Label success; Label success;
if (instr->OutputCount() > 1) { if (instr->OutputCount() > 1) {
__ Set(i.OutputRegister(1), 0); __ Set(i.OutputRegister(1), 0);
__ xorps(kScratchDoubleReg, kScratchDoubleReg);
if (instr->InputAt(0)->IsDoubleRegister()) {
__ Ucomiss(kScratchDoubleReg, i.InputDoubleRegister(0));
} else {
__ Ucomiss(kScratchDoubleReg, i.InputOperand(0));
}
__ j(above, &done);
} }
// There does not exist a Float32ToUint64 instruction, so we have to use // There does not exist a Float32ToUint64 instruction, so we have to use
// the Float32ToInt64 instruction. // the Float32ToInt64 instruction.
...@@ -1160,14 +1152,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { ...@@ -1160,14 +1152,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
Label success; Label success;
if (instr->OutputCount() > 1) { if (instr->OutputCount() > 1) {
__ Set(i.OutputRegister(1), 0); __ Set(i.OutputRegister(1), 0);
__ xorps(kScratchDoubleReg, kScratchDoubleReg);
if (instr->InputAt(0)->IsDoubleRegister()) {
__ Ucomisd(kScratchDoubleReg, i.InputDoubleRegister(0));
} else {
__ Ucomisd(kScratchDoubleReg, i.InputOperand(0));
}
__ j(above, &done);
} }
// There does not exist a Float64ToUint64 instruction, so we have to use // There does not exist a Float64ToUint64 instruction, so we have to use
// the Float64ToInt64 instruction. // the Float64ToInt64 instruction.
......
...@@ -1705,9 +1705,9 @@ void MacroAssembler::Trunc_ul_d(FPURegister fd, Register rs, ...@@ -1705,9 +1705,9 @@ void MacroAssembler::Trunc_ul_d(FPURegister fd, Register rs,
Label simple_convert, done, fail; Label simple_convert, done, fail;
if (result.is_valid()) { if (result.is_valid()) {
mov(result, zero_reg); mov(result, zero_reg);
Move(kDoubleRegZero, 0.0); Move(scratch, -1.0);
// If fd < 0 or unordered, then the conversion fails. // If fd =< -1 or unordered, then the conversion fails.
BranchF(&fail, &fail, lt, fd, kDoubleRegZero); BranchF(&fail, &fail, le, fd, scratch);
} }
// Load 2^63 into scratch as its double representation. // Load 2^63 into scratch as its double representation.
...@@ -1753,9 +1753,9 @@ void MacroAssembler::Trunc_ul_s(FPURegister fd, Register rs, ...@@ -1753,9 +1753,9 @@ void MacroAssembler::Trunc_ul_s(FPURegister fd, Register rs,
Label simple_convert, done, fail; Label simple_convert, done, fail;
if (result.is_valid()) { if (result.is_valid()) {
mov(result, zero_reg); mov(result, zero_reg);
Move(kDoubleRegZero, 0.0); Move(scratch, -1.0f);
// If fd < 0 or unordered, then the conversion fails. // If fd =< -1 or unordered, then the conversion fails.
BranchF32(&fail, &fail, lt, fd, kDoubleRegZero); BranchF32(&fail, &fail, le, fd, scratch);
} }
// Load 2^63 into scratch as its float representation. // Load 2^63 into scratch as its float representation.
......
...@@ -5529,21 +5529,18 @@ TEST(RunTryTruncateFloat64ToInt64WithCheck) { ...@@ -5529,21 +5529,18 @@ TEST(RunTryTruncateFloat64ToInt64WithCheck) {
} }
TEST(RunTruncateFloat32ToUint64) { TEST(RunTryTruncateFloat32ToUint64WithoutCheck) {
BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float32()); BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float32());
m.Return(m.TryTruncateFloat32ToUint64(m.Parameter(0))); m.Return(m.TryTruncateFloat32ToUint64(m.Parameter(0)));
FOR_UINT64_INPUTS(i) { FOR_UINT64_INPUTS(i) {
float input = static_cast<float>(*i); float input = static_cast<float>(*i);
if (input < 18446744073709551616.0) { // This condition on 'input' is required because
// static_cast<float>(UINT64_MAX) results in a value outside uint64 range.
if (input < static_cast<float>(UINT64_MAX)) {
CHECK_EQ(static_cast<uint64_t>(input), m.Call(input)); CHECK_EQ(static_cast<uint64_t>(input), m.Call(input));
} }
} }
FOR_FLOAT32_INPUTS(j) {
if (*j < 18446744073709551616.0 && *j >= 0) {
CHECK_EQ(static_cast<uint64_t>(*j), m.Call(*j));
}
}
} }
...@@ -5557,7 +5554,7 @@ TEST(RunTryTruncateFloat32ToUint64WithCheck) { ...@@ -5557,7 +5554,7 @@ TEST(RunTryTruncateFloat32ToUint64WithCheck) {
m.Return(val); m.Return(val);
FOR_FLOAT32_INPUTS(i) { FOR_FLOAT32_INPUTS(i) {
if (*i < 18446744073709551616.0 && *i >= 0.0) { if (*i < static_cast<float>(UINT64_MAX) && *i > -1.0) {
// Conversions within this range should succeed. // Conversions within this range should succeed.
CHECK_EQ(static_cast<uint64_t>(*i), m.Call(*i)); CHECK_EQ(static_cast<uint64_t>(*i), m.Call(*i));
CHECK_NE(0, success); CHECK_NE(0, success);
...@@ -5576,7 +5573,7 @@ TEST(RunTryTruncateFloat64ToUint64WithoutCheck) { ...@@ -5576,7 +5573,7 @@ TEST(RunTryTruncateFloat64ToUint64WithoutCheck) {
FOR_UINT64_INPUTS(j) { FOR_UINT64_INPUTS(j) {
double input = static_cast<double>(*j); double input = static_cast<double>(*j);
if (input < 18446744073709551616.0) { if (input < static_cast<float>(UINT64_MAX)) {
CHECK_EQ(static_cast<uint64_t>(input), m.Call(input)); CHECK_EQ(static_cast<uint64_t>(input), m.Call(input));
} }
} }
...@@ -5593,7 +5590,7 @@ TEST(RunTryTruncateFloat64ToUint64WithCheck) { ...@@ -5593,7 +5590,7 @@ TEST(RunTryTruncateFloat64ToUint64WithCheck) {
m.Return(val); m.Return(val);
FOR_FLOAT64_INPUTS(i) { FOR_FLOAT64_INPUTS(i) {
if (*i < 18446744073709551616.0 && *i >= 0) { if (*i < 18446744073709551616.0 && *i > -1) {
// Conversions within this range should succeed. // Conversions within this range should succeed.
CHECK_EQ(static_cast<uint64_t>(*i), m.Call(*i)); CHECK_EQ(static_cast<uint64_t>(*i), m.Call(*i));
CHECK_NE(0, success); CHECK_NE(0, success);
......
...@@ -104,6 +104,7 @@ class ValueHelper { ...@@ -104,6 +104,7 @@ class ValueHelper {
-62.0f, -62.0f,
-15.0f, -15.0f,
-7.0f, -7.0f,
-1.0f,
-0.0256635f, -0.0256635f,
-4.60374e-07f, -4.60374e-07f,
-3.63759e-10f, -3.63759e-10f,
...@@ -133,6 +134,7 @@ class ValueHelper { ...@@ -133,6 +134,7 @@ class ValueHelper {
5.57888e-07f, 5.57888e-07f,
4.89988e-05f, 4.89988e-05f,
0.244326f, 0.244326f,
1.0f,
12.4895f, 12.4895f,
19.0f, 19.0f,
47.0f, 47.0f,
...@@ -186,6 +188,7 @@ class ValueHelper { ...@@ -186,6 +188,7 @@ class ValueHelper {
-999.75, -999.75,
-2e66, -2e66,
-1.75, -1.75,
-1.0,
-0.5, -0.5,
-0.0, -0.0,
0.0, 0.0,
...@@ -194,6 +197,7 @@ class ValueHelper { ...@@ -194,6 +197,7 @@ class ValueHelper {
0.25, 0.25,
0.375, 0.375,
0.5, 0.5,
1.0,
1.25, 1.25,
2, 2,
3.1e7, 3.1e7,
......
...@@ -3408,7 +3408,7 @@ TEST(Run_Wasm_I64UConvertF32) { ...@@ -3408,7 +3408,7 @@ TEST(Run_Wasm_I64UConvertF32) {
BUILD(r, WASM_I64_UCONVERT_F32(WASM_GET_LOCAL(0))); BUILD(r, WASM_I64_UCONVERT_F32(WASM_GET_LOCAL(0)));
FOR_FLOAT32_INPUTS(i) { FOR_FLOAT32_INPUTS(i) {
if (*i < 18446744073709551616.0 && *i >= 0) { if (*i < static_cast<float>(UINT64_MAX) && *i > -1) {
CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i)); CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i));
} else { } else {
CHECK_TRAP64(r.Call(*i)); CHECK_TRAP64(r.Call(*i));
...@@ -3422,7 +3422,7 @@ TEST(Run_Wasm_I64UConvertF64) { ...@@ -3422,7 +3422,7 @@ TEST(Run_Wasm_I64UConvertF64) {
BUILD(r, WASM_I64_UCONVERT_F64(WASM_GET_LOCAL(0))); BUILD(r, WASM_I64_UCONVERT_F64(WASM_GET_LOCAL(0)));
FOR_FLOAT64_INPUTS(i) { FOR_FLOAT64_INPUTS(i) {
if (*i < 18446744073709551616.0 && *i >= 0) { if (*i < static_cast<float>(UINT64_MAX) && *i > -1) {
CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i)); CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i));
} else { } else {
CHECK_TRAP64(r.Call(*i)); CHECK_TRAP64(r.Call(*i));
......
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