Commit 4f494789 authored by ahaas's avatar ahaas Committed by Commit bot

[turbofan] Implemented the optional Float32RoundUp operator.

The Float32RoundUp operator rounds float32 numbers towards infinity.
The operator is currently implemented on x64, ia32, arm, and arm64.

R=titzer@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#32262}
parent 74434403
......@@ -3390,6 +3390,20 @@ void Assembler::vrintn(const DwVfpRegister dst, const DwVfpRegister src) {
}
void Assembler::vrintp(const SwVfpRegister dst, const SwVfpRegister src) {
// cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) |
// 10(19-18) | RM=10(17-16) | Vd(15-12) | 101(11-9) | sz=0(8) | 01(7-6) |
// M(5) | 0(4) | Vm(3-0)
DCHECK(CpuFeatures::IsSupported(ARMv8));
int vd, d;
dst.split_code(&vd, &d);
int vm, m;
src.split_code(&vm, &m);
emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | 0x2 * B16 |
vd * B12 | 0x5 * B9 | B6 | m * B5 | vm);
}
void Assembler::vrintp(const DwVfpRegister dst, const DwVfpRegister src) {
// cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) |
// 10(19-18) | RM=10(17-16) | Vd(15-12) | 101(11-9) | sz=1(8) | 01(7-6) |
......
......@@ -1215,6 +1215,7 @@ class Assembler : public AssemblerBase {
void vrintn(const DwVfpRegister dst, const DwVfpRegister src);
void vrintm(const SwVfpRegister dst, const SwVfpRegister src);
void vrintm(const DwVfpRegister dst, const DwVfpRegister src);
void vrintp(const SwVfpRegister dst, const SwVfpRegister src);
void vrintp(const DwVfpRegister dst, const DwVfpRegister src);
void vrintz(const DwVfpRegister dst, const DwVfpRegister src,
const Condition cond = al);
......
......@@ -726,9 +726,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
case kArmVnegF32:
__ vneg(i.OutputFloat32Register(), i.InputFloat32Register(0));
break;
case kArmVrintmF32:
__ vrintm(i.OutputFloat32Register(), i.InputFloat32Register(0));
break;
case kArmVcmpF64:
if (instr->InputAt(1)->IsDoubleRegister()) {
__ VFPCompareAndSetFlags(i.InputFloat64Register(0),
......@@ -794,9 +791,15 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
case kArmVnegF64:
__ vneg(i.OutputFloat64Register(), i.InputFloat64Register(0));
break;
case kArmVrintmF32:
__ vrintm(i.OutputFloat32Register(), i.InputFloat32Register(0));
break;
case kArmVrintmF64:
__ vrintm(i.OutputFloat64Register(), i.InputFloat64Register(0));
break;
case kArmVrintpF32:
__ vrintp(i.OutputFloat32Register(), i.InputFloat32Register(0));
break;
case kArmVrintpF64:
__ vrintp(i.OutputFloat64Register(), i.InputFloat64Register(0));
break;
......
......@@ -54,7 +54,6 @@ namespace compiler {
V(ArmVabsF32) \
V(ArmVnegF32) \
V(ArmVsqrtF32) \
V(ArmVrintmF32) \
V(ArmVcmpF64) \
V(ArmVaddF64) \
V(ArmVsubF64) \
......@@ -66,7 +65,9 @@ namespace compiler {
V(ArmVabsF64) \
V(ArmVnegF64) \
V(ArmVsqrtF64) \
V(ArmVrintmF32) \
V(ArmVrintmF64) \
V(ArmVrintpF32) \
V(ArmVrintpF64) \
V(ArmVrintzF64) \
V(ArmVrintaF64) \
......
......@@ -1125,6 +1125,11 @@ void InstructionSelector::VisitFloat64RoundDown(Node* node) {
}
void InstructionSelector::VisitFloat32RoundUp(Node* node) {
VisitRR(this, kArmVrintpF32, node);
}
void InstructionSelector::VisitFloat64RoundUp(Node* node) {
VisitRR(this, kArmVrintpF64, node);
}
......@@ -1570,12 +1575,13 @@ InstructionSelector::SupportedMachineOperatorFlags() {
MachineOperatorBuilder::kInt32DivIsSafe |
MachineOperatorBuilder::kUint32DivIsSafe;
if (CpuFeatures::IsSupported(ARMv8)) {
flags |= MachineOperatorBuilder::kFloat64RoundDown |
flags |= MachineOperatorBuilder::kFloat32RoundDown |
MachineOperatorBuilder::kFloat64RoundDown |
MachineOperatorBuilder::kFloat32RoundUp |
MachineOperatorBuilder::kFloat64RoundUp |
MachineOperatorBuilder::kFloat64RoundTruncate |
MachineOperatorBuilder::kFloat64RoundTiesAway |
MachineOperatorBuilder::kFloat64RoundTiesEven |
MachineOperatorBuilder::kFloat32RoundDown;
MachineOperatorBuilder::kFloat64RoundTiesEven;
}
return flags;
}
......
......@@ -629,6 +629,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
case kArm64Float64RoundDown:
__ Frintm(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;
case kArm64Float32RoundUp:
__ Frintp(i.OutputFloat32Register(), i.InputFloat32Register(0));
break;
case kArm64Float64RoundUp:
__ Frintp(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;
......
......@@ -101,6 +101,7 @@ namespace compiler {
V(Arm64Float64Neg) \
V(Arm64Float64Sqrt) \
V(Arm64Float64RoundDown) \
V(Arm64Float32RoundUp) \
V(Arm64Float64RoundUp) \
V(Arm64Float64RoundTiesAway) \
V(Arm64Float64RoundTruncate) \
......
......@@ -1483,6 +1483,11 @@ void InstructionSelector::VisitFloat64RoundDown(Node* node) {
}
void InstructionSelector::VisitFloat32RoundUp(Node* node) {
VisitRR(this, kArm64Float32RoundUp, node);
}
void InstructionSelector::VisitFloat64RoundUp(Node* node) {
VisitRR(this, kArm64Float64RoundUp, node);
}
......@@ -2073,6 +2078,7 @@ InstructionSelector::SupportedMachineOperatorFlags() {
MachineOperatorBuilder::kFloat64Max |
MachineOperatorBuilder::kFloat64Min |
MachineOperatorBuilder::kFloat64RoundDown |
MachineOperatorBuilder::kFloat32RoundUp |
MachineOperatorBuilder::kFloat64RoundUp |
MachineOperatorBuilder::kFloat64RoundTruncate |
MachineOperatorBuilder::kFloat64RoundTiesAway |
......
......@@ -861,6 +861,11 @@ void InstructionSelector::VisitFloat64RoundDown(Node* node) {
}
void InstructionSelector::VisitFloat32RoundUp(Node* node) {
VisitRR(this, node, kSSEFloat32Round | MiscField::encode(kRoundUp));
}
void InstructionSelector::VisitFloat64RoundUp(Node* node) {
VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundUp));
}
......@@ -1289,11 +1294,12 @@ InstructionSelector::SupportedMachineOperatorFlags() {
flags |= MachineOperatorBuilder::kWord32Popcnt;
}
if (CpuFeatures::IsSupported(SSE4_1)) {
flags |= MachineOperatorBuilder::kFloat64RoundDown |
flags |= MachineOperatorBuilder::kFloat32RoundDown |
MachineOperatorBuilder::kFloat64RoundDown |
MachineOperatorBuilder::kFloat32RoundUp |
MachineOperatorBuilder::kFloat64RoundUp |
MachineOperatorBuilder::kFloat64RoundTruncate |
MachineOperatorBuilder::kFloat64RoundTiesEven |
MachineOperatorBuilder::kFloat32RoundDown;
MachineOperatorBuilder::kFloat64RoundTiesEven;
}
return flags;
}
......
......@@ -927,6 +927,8 @@ void InstructionSelector::VisitNode(Node* node) {
return MarkAsFloat32(node), VisitFloat32RoundDown(node);
case IrOpcode::kFloat64RoundDown:
return MarkAsFloat64(node), VisitFloat64RoundDown(node);
case IrOpcode::kFloat32RoundUp:
return MarkAsFloat32(node), VisitFloat32RoundUp(node);
case IrOpcode::kFloat64RoundUp:
return MarkAsFloat64(node), VisitFloat64RoundUp(node);
case IrOpcode::kFloat64RoundTruncate:
......
......@@ -188,6 +188,7 @@ CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) {
V(Float64Min, Operator::kNoProperties, 2, 0, 1) \
V(Float32RoundDown, Operator::kNoProperties, 1, 0, 1) \
V(Float64RoundDown, Operator::kNoProperties, 1, 0, 1) \
V(Float32RoundUp, Operator::kNoProperties, 1, 0, 1) \
V(Float64RoundUp, Operator::kNoProperties, 1, 0, 1) \
V(Float64RoundTruncate, Operator::kNoProperties, 1, 0, 1) \
V(Float64RoundTiesAway, Operator::kNoProperties, 1, 0, 1) \
......
......@@ -118,22 +118,23 @@ class MachineOperatorBuilder final : public ZoneObject {
kFloat64Min = 1u << 3,
kFloat32RoundDown = 1u << 4,
kFloat64RoundDown = 1u << 5,
kFloat64RoundUp = 1u << 6,
kFloat64RoundTruncate = 1u << 7,
kFloat64RoundTiesEven = 1u << 8,
kFloat64RoundTiesAway = 1u << 9,
kInt32DivIsSafe = 1u << 10,
kUint32DivIsSafe = 1u << 11,
kWord32ShiftIsSafe = 1u << 12,
kWord32Ctz = 1u << 13,
kWord64Ctz = 1u << 14,
kWord32Popcnt = 1u << 15,
kWord64Popcnt = 1u << 16,
kFloat32RoundUp = 1u << 6,
kFloat64RoundUp = 1u << 7,
kFloat64RoundTruncate = 1u << 8,
kFloat64RoundTiesEven = 1u << 9,
kFloat64RoundTiesAway = 1u << 10,
kInt32DivIsSafe = 1u << 11,
kUint32DivIsSafe = 1u << 12,
kWord32ShiftIsSafe = 1u << 13,
kWord32Ctz = 1u << 14,
kWord64Ctz = 1u << 15,
kWord32Popcnt = 1u << 16,
kWord64Popcnt = 1u << 17,
kAllOptionalOps = kFloat32Max | kFloat32Min | kFloat64Max | kFloat64Min |
kFloat64RoundDown | kFloat64RoundUp |
kFloat64RoundTruncate | kFloat64RoundTiesAway |
kFloat64RoundTiesEven | kWord32Ctz | kWord64Ctz |
kWord32Popcnt | kWord64Popcnt | kFloat32RoundDown
kFloat32RoundDown | kFloat64RoundDown | kFloat32RoundUp |
kFloat64RoundUp | kFloat64RoundTruncate |
kFloat64RoundTiesAway | kFloat64RoundTiesEven |
kWord32Ctz | kWord64Ctz | kWord32Popcnt | kWord64Popcnt
};
typedef base::Flags<Flag, unsigned> Flags;
......@@ -271,6 +272,7 @@ class MachineOperatorBuilder final : public ZoneObject {
// Floating point rounding.
const OptionalOperator Float32RoundDown();
const OptionalOperator Float64RoundDown();
const OptionalOperator Float32RoundUp();
const OptionalOperator Float64RoundUp();
const OptionalOperator Float64RoundTruncate();
const OptionalOperator Float64RoundTiesAway();
......
......@@ -655,6 +655,9 @@ void InstructionSelector::VisitFloat64RoundDown(Node* node) {
}
void InstructionSelector::VisitFloat32RoundUp(Node* node) { UNREACHABLE(); }
void InstructionSelector::VisitFloat64RoundUp(Node* node) {
VisitRR(this, kMipsFloat64RoundUp, node);
}
......
......@@ -989,6 +989,9 @@ void InstructionSelector::VisitFloat64RoundDown(Node* node) {
}
void InstructionSelector::VisitFloat32RoundUp(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitFloat64RoundUp(Node* node) {
VisitRR(this, kMips64Float64RoundUp, node);
}
......
......@@ -305,6 +305,7 @@
V(Float64Abs) \
V(Float64Sqrt) \
V(Float64RoundDown) \
V(Float32RoundUp) \
V(Float64RoundUp) \
V(Float64RoundTruncate) \
V(Float64RoundTiesAway) \
......
......@@ -1136,6 +1136,9 @@ void InstructionSelector::VisitFloat64RoundDown(Node* node) {
}
void InstructionSelector::VisitFloat32RoundUp(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitFloat64RoundUp(Node* node) {
VisitRR(this, kPPC_CeilDouble, node);
}
......
......@@ -489,6 +489,9 @@ class RawMachineAssembler {
Node* Float64RoundDown(Node* a) {
return AddNode(machine()->Float64RoundDown().op(), a);
}
Node* Float32RoundUp(Node* a) {
return AddNode(machine()->Float32RoundUp().op(), a);
}
Node* Float64RoundUp(Node* a) {
return AddNode(machine()->Float64RoundUp().op(), a);
}
......
......@@ -2277,6 +2277,12 @@ Type* Typer::Visitor::TypeFloat64RoundDown(Node* node) {
}
Type* Typer::Visitor::TypeFloat32RoundUp(Node* node) {
// TODO(sigurds): We could have a tighter bound here.
return Type::Number();
}
Type* Typer::Visitor::TypeFloat64RoundUp(Node* node) {
// TODO(sigurds): We could have a tighter bound here.
return Type::Number();
......
......@@ -890,6 +890,7 @@ void Verifier::Visitor::Check(Node* node) {
case IrOpcode::kFloat64Sqrt:
case IrOpcode::kFloat32RoundDown:
case IrOpcode::kFloat64RoundDown:
case IrOpcode::kFloat32RoundUp:
case IrOpcode::kFloat64RoundUp:
case IrOpcode::kFloat64RoundTruncate:
case IrOpcode::kFloat64RoundTiesAway:
......
......@@ -1148,6 +1148,11 @@ void InstructionSelector::VisitFloat64RoundDown(Node* node) {
}
void InstructionSelector::VisitFloat32RoundUp(Node* node) {
VisitRR(this, node, kSSEFloat32Round | MiscField::encode(kRoundUp));
}
void InstructionSelector::VisitFloat64RoundUp(Node* node) {
VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundUp));
}
......@@ -1696,11 +1701,12 @@ InstructionSelector::SupportedMachineOperatorFlags() {
MachineOperatorBuilder::kWord64Popcnt;
}
if (CpuFeatures::IsSupported(SSE4_1)) {
flags |= MachineOperatorBuilder::kFloat64RoundDown |
flags |= MachineOperatorBuilder::kFloat32RoundDown |
MachineOperatorBuilder::kFloat64RoundDown |
MachineOperatorBuilder::kFloat32RoundUp |
MachineOperatorBuilder::kFloat64RoundUp |
MachineOperatorBuilder::kFloat64RoundTruncate |
MachineOperatorBuilder::kFloat64RoundTiesEven |
MachineOperatorBuilder::kFloat32RoundDown;
MachineOperatorBuilder::kFloat64RoundTiesEven;
}
return flags;
}
......
......@@ -852,6 +852,9 @@ void InstructionSelector::VisitFloat64RoundDown(Node* node) {
}
void InstructionSelector::VisitFloat32RoundUp(Node* node) { UNREACHABLE(); }
void InstructionSelector::VisitFloat64RoundUp(Node* node) { UNREACHABLE(); }
......
......@@ -5177,6 +5177,15 @@ TEST(RunFloat64RoundDown2) {
}
TEST(RunFloat32RoundUp) {
BufferedRawMachineAssemblerTester<float> m(kMachFloat32);
if (!m.machine()->Float32RoundUp().IsSupported()) return;
m.Return(m.Float32RoundUp(m.Parameter(0)));
FOR_FLOAT32_INPUTS(i) { CheckFloatEq(std::ceil(*i), m.Call(*i)); }
}
TEST(RunFloat64RoundUp) {
BufferedRawMachineAssemblerTester<double> m(kMachFloat64);
if (!m.machine()->Float64RoundUp().IsSupported()) return;
......
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