[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}
This commit is contained in:
ahaas 2015-12-17 02:24:36 -08:00 committed by Commit bot
parent fe484ff648
commit 0794c3c9b9
6 changed files with 23 additions and 38 deletions

View File

@ -1070,16 +1070,16 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
case kArm64Float32ToUint64:
__ Fcvtzu(i.OutputRegister64(), i.InputFloat32Register(0));
if (i.OutputCount() > 1) {
__ Fcmp(i.InputFloat32Register(0), 0.0);
__ Ccmp(i.OutputRegister(0), -1, ZFlag, ge);
__ Fcmp(i.InputFloat32Register(0), -1.0);
__ Ccmp(i.OutputRegister(0), -1, ZFlag, gt);
__ Cset(i.OutputRegister(1), ne);
}
break;
case kArm64Float64ToUint64:
__ Fcvtzu(i.OutputRegister64(), i.InputDoubleRegister(0));
if (i.OutputCount() > 1) {
__ Fcmp(i.InputDoubleRegister(0), 0.0);
__ Ccmp(i.OutputRegister(0), -1, ZFlag, ge);
__ Fcmp(i.InputDoubleRegister(0), -1.0);
__ Ccmp(i.OutputRegister(0), -1, ZFlag, gt);
__ Cset(i.OutputRegister(1), ne);
}
break;

View File

@ -1109,14 +1109,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
Label success;
if (instr->OutputCount() > 1) {
__ 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
// the Float32ToInt64 instruction.
@ -1160,14 +1152,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
Label success;
if (instr->OutputCount() > 1) {
__ 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
// the Float64ToInt64 instruction.

View File

@ -1705,9 +1705,9 @@ void MacroAssembler::Trunc_ul_d(FPURegister fd, Register rs,
Label simple_convert, done, fail;
if (result.is_valid()) {
mov(result, zero_reg);
Move(kDoubleRegZero, 0.0);
// If fd < 0 or unordered, then the conversion fails.
BranchF(&fail, &fail, lt, fd, kDoubleRegZero);
Move(scratch, -1.0);
// If fd =< -1 or unordered, then the conversion fails.
BranchF(&fail, &fail, le, fd, scratch);
}
// Load 2^63 into scratch as its double representation.
@ -1753,9 +1753,9 @@ void MacroAssembler::Trunc_ul_s(FPURegister fd, Register rs,
Label simple_convert, done, fail;
if (result.is_valid()) {
mov(result, zero_reg);
Move(kDoubleRegZero, 0.0);
// If fd < 0 or unordered, then the conversion fails.
BranchF32(&fail, &fail, lt, fd, kDoubleRegZero);
Move(scratch, -1.0f);
// If fd =< -1 or unordered, then the conversion fails.
BranchF32(&fail, &fail, le, fd, scratch);
}
// Load 2^63 into scratch as its float representation.

View File

@ -5529,21 +5529,18 @@ TEST(RunTryTruncateFloat64ToInt64WithCheck) {
}
TEST(RunTruncateFloat32ToUint64) {
TEST(RunTryTruncateFloat32ToUint64WithoutCheck) {
BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float32());
m.Return(m.TryTruncateFloat32ToUint64(m.Parameter(0)));
FOR_UINT64_INPUTS(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));
}
}
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) {
m.Return(val);
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.
CHECK_EQ(static_cast<uint64_t>(*i), m.Call(*i));
CHECK_NE(0, success);
@ -5576,7 +5573,7 @@ TEST(RunTryTruncateFloat64ToUint64WithoutCheck) {
FOR_UINT64_INPUTS(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));
}
}
@ -5593,7 +5590,7 @@ TEST(RunTryTruncateFloat64ToUint64WithCheck) {
m.Return(val);
FOR_FLOAT64_INPUTS(i) {
if (*i < 18446744073709551616.0 && *i >= 0) {
if (*i < 18446744073709551616.0 && *i > -1) {
// Conversions within this range should succeed.
CHECK_EQ(static_cast<uint64_t>(*i), m.Call(*i));
CHECK_NE(0, success);

View File

@ -104,6 +104,7 @@ class ValueHelper {
-62.0f,
-15.0f,
-7.0f,
-1.0f,
-0.0256635f,
-4.60374e-07f,
-3.63759e-10f,
@ -133,6 +134,7 @@ class ValueHelper {
5.57888e-07f,
4.89988e-05f,
0.244326f,
1.0f,
12.4895f,
19.0f,
47.0f,
@ -186,6 +188,7 @@ class ValueHelper {
-999.75,
-2e66,
-1.75,
-1.0,
-0.5,
-0.0,
0.0,
@ -194,6 +197,7 @@ class ValueHelper {
0.25,
0.375,
0.5,
1.0,
1.25,
2,
3.1e7,

View File

@ -3408,7 +3408,7 @@ TEST(Run_Wasm_I64UConvertF32) {
BUILD(r, WASM_I64_UCONVERT_F32(WASM_GET_LOCAL(0)));
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));
} else {
CHECK_TRAP64(r.Call(*i));
@ -3422,7 +3422,7 @@ TEST(Run_Wasm_I64UConvertF64) {
BUILD(r, WASM_I64_UCONVERT_F64(WASM_GET_LOCAL(0)));
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));
} else {
CHECK_TRAP64(r.Call(*i));