Commit 1b535ca0 authored by ahaas's avatar ahaas Committed by Commit bot

Implemented the RoundInt64ToFloat32 TurboFan operator for x64, arm64, and mips64.

R=titzer@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#31929}
parent 01fd8e05
...@@ -974,6 +974,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { ...@@ -974,6 +974,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
case kArm64Int32ToFloat64: case kArm64Int32ToFloat64:
__ Scvtf(i.OutputDoubleRegister(), i.InputRegister32(0)); __ Scvtf(i.OutputDoubleRegister(), i.InputRegister32(0));
break; break;
case kArm64Int64ToFloat32:
__ Scvtf(i.OutputDoubleRegister().S(), i.InputRegister64(0));
break;
case kArm64Int64ToFloat64: case kArm64Int64ToFloat64:
__ Scvtf(i.OutputDoubleRegister(), i.InputRegister64(0)); __ Scvtf(i.OutputDoubleRegister(), i.InputRegister64(0));
break; break;
......
...@@ -108,6 +108,7 @@ namespace compiler { ...@@ -108,6 +108,7 @@ namespace compiler {
V(Arm64Float64ToInt32) \ V(Arm64Float64ToInt32) \
V(Arm64Float64ToUint32) \ V(Arm64Float64ToUint32) \
V(Arm64Int32ToFloat64) \ V(Arm64Int32ToFloat64) \
V(Arm64Int64ToFloat32) \
V(Arm64Int64ToFloat64) \ V(Arm64Int64ToFloat64) \
V(Arm64Uint32ToFloat64) \ V(Arm64Uint32ToFloat64) \
V(Arm64Float64ExtractLowWord32) \ V(Arm64Float64ExtractLowWord32) \
......
...@@ -1316,6 +1316,11 @@ void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { ...@@ -1316,6 +1316,11 @@ void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
} }
void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) {
VisitRR(this, kArm64Int64ToFloat32, node);
}
void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) { void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) {
VisitRR(this, kArm64Int64ToFloat64, node); VisitRR(this, kArm64Int64ToFloat64, node);
} }
......
...@@ -816,6 +816,8 @@ void InstructionSelector::VisitNode(Node* node) { ...@@ -816,6 +816,8 @@ void InstructionSelector::VisitNode(Node* node) {
return MarkAsWord32(node), VisitTruncateFloat64ToInt32(node); return MarkAsWord32(node), VisitTruncateFloat64ToInt32(node);
case IrOpcode::kTruncateInt64ToInt32: case IrOpcode::kTruncateInt64ToInt32:
return MarkAsWord32(node), VisitTruncateInt64ToInt32(node); return MarkAsWord32(node), VisitTruncateInt64ToInt32(node);
case IrOpcode::kRoundInt64ToFloat32:
return MarkAsFloat32(node), VisitRoundInt64ToFloat32(node);
case IrOpcode::kRoundInt64ToFloat64: case IrOpcode::kRoundInt64ToFloat64:
return MarkAsFloat64(node), VisitRoundInt64ToFloat64(node); return MarkAsFloat64(node), VisitRoundInt64ToFloat64(node);
case IrOpcode::kBitcastFloat32ToInt32: case IrOpcode::kBitcastFloat32ToInt32:
...@@ -1041,6 +1043,11 @@ void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { ...@@ -1041,6 +1043,11 @@ void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
} }
void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) {
UNIMPLEMENTED();
}
void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) { void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) {
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
......
...@@ -136,6 +136,7 @@ CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) { ...@@ -136,6 +136,7 @@ CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) {
V(ChangeFloat64ToInt32, Operator::kNoProperties, 1, 0, 1) \ V(ChangeFloat64ToInt32, Operator::kNoProperties, 1, 0, 1) \
V(ChangeFloat64ToUint32, Operator::kNoProperties, 1, 0, 1) \ V(ChangeFloat64ToUint32, Operator::kNoProperties, 1, 0, 1) \
V(ChangeInt32ToFloat64, Operator::kNoProperties, 1, 0, 1) \ V(ChangeInt32ToFloat64, Operator::kNoProperties, 1, 0, 1) \
V(RoundInt64ToFloat32, Operator::kNoProperties, 1, 0, 1) \
V(RoundInt64ToFloat64, Operator::kNoProperties, 1, 0, 1) \ V(RoundInt64ToFloat64, Operator::kNoProperties, 1, 0, 1) \
V(ChangeInt32ToInt64, Operator::kNoProperties, 1, 0, 1) \ V(ChangeInt32ToInt64, Operator::kNoProperties, 1, 0, 1) \
V(ChangeUint32ToFloat64, Operator::kNoProperties, 1, 0, 1) \ V(ChangeUint32ToFloat64, Operator::kNoProperties, 1, 0, 1) \
......
...@@ -209,6 +209,7 @@ class MachineOperatorBuilder final : public ZoneObject { ...@@ -209,6 +209,7 @@ class MachineOperatorBuilder final : public ZoneObject {
const Operator* TruncateFloat64ToFloat32(); const Operator* TruncateFloat64ToFloat32();
const Operator* TruncateFloat64ToInt32(TruncationMode); const Operator* TruncateFloat64ToInt32(TruncationMode);
const Operator* TruncateInt64ToInt32(); const Operator* TruncateInt64ToInt32();
const Operator* RoundInt64ToFloat32();
const Operator* RoundInt64ToFloat64(); const Operator* RoundInt64ToFloat64();
// These operators reinterpret the bits of a floating point number as an // These operators reinterpret the bits of a floating point number as an
......
...@@ -917,6 +917,12 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { ...@@ -917,6 +917,12 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
__ cvt_d_w(i.OutputDoubleRegister(), scratch); __ cvt_d_w(i.OutputDoubleRegister(), scratch);
break; break;
} }
case kMips64CvtSL: {
FPURegister scratch = kScratchDoubleReg;
__ dmtc1(i.InputRegister(0), scratch);
__ cvt_s_l(i.OutputDoubleRegister(), scratch);
break;
}
case kMips64CvtDL: { case kMips64CvtDL: {
FPURegister scratch = kScratchDoubleReg; FPURegister scratch = kScratchDoubleReg;
__ dmtc1(i.InputRegister(0), scratch); __ dmtc1(i.InputRegister(0), scratch);
......
...@@ -74,6 +74,7 @@ namespace compiler { ...@@ -74,6 +74,7 @@ namespace compiler {
V(Mips64TruncWD) \ V(Mips64TruncWD) \
V(Mips64TruncUwD) \ V(Mips64TruncUwD) \
V(Mips64CvtDW) \ V(Mips64CvtDW) \
V(Mips64CvtSL) \
V(Mips64CvtDL) \ V(Mips64CvtDL) \
V(Mips64CvtDUw) \ V(Mips64CvtDUw) \
V(Mips64Lb) \ V(Mips64Lb) \
......
...@@ -617,6 +617,11 @@ void InstructionSelector::VisitTruncateFloat64ToInt32(Node* node) { ...@@ -617,6 +617,11 @@ void InstructionSelector::VisitTruncateFloat64ToInt32(Node* node) {
} }
void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) {
VisitRR(this, kMips64CvtSL, node);
}
void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) { void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) {
VisitRR(this, kMips64CvtDL, node); VisitRR(this, kMips64CvtDL, node);
} }
......
...@@ -274,6 +274,7 @@ ...@@ -274,6 +274,7 @@
V(TruncateFloat64ToInt32) \ V(TruncateFloat64ToInt32) \
V(TruncateInt64ToInt32) \ V(TruncateInt64ToInt32) \
V(RoundInt64ToFloat64) \ V(RoundInt64ToFloat64) \
V(RoundInt64ToFloat32) \
V(BitcastFloat32ToInt32) \ V(BitcastFloat32ToInt32) \
V(BitcastFloat64ToInt64) \ V(BitcastFloat64ToInt64) \
V(BitcastInt32ToFloat32) \ V(BitcastInt32ToFloat32) \
......
...@@ -458,6 +458,9 @@ class RawMachineAssembler { ...@@ -458,6 +458,9 @@ class RawMachineAssembler {
Node* TruncateInt64ToInt32(Node* a) { Node* TruncateInt64ToInt32(Node* a) {
return AddNode(machine()->TruncateInt64ToInt32(), a); return AddNode(machine()->TruncateInt64ToInt32(), a);
} }
Node* RoundInt64ToFloat32(Node* a) {
return AddNode(machine()->RoundInt64ToFloat32(), a);
}
Node* RoundInt64ToFloat64(Node* a) { Node* RoundInt64ToFloat64(Node* a) {
return AddNode(machine()->RoundInt64ToFloat64(), a); return AddNode(machine()->RoundInt64ToFloat64(), a);
} }
......
...@@ -2110,6 +2110,11 @@ Type* Typer::Visitor::TypeTruncateInt64ToInt32(Node* node) { ...@@ -2110,6 +2110,11 @@ Type* Typer::Visitor::TypeTruncateInt64ToInt32(Node* node) {
} }
Type* Typer::Visitor::TypeRoundInt64ToFloat32(Node* node) {
return Type::Intersect(Type::PlainNumber(), Type::UntaggedFloat32(), zone());
}
Type* Typer::Visitor::TypeRoundInt64ToFloat64(Node* node) { Type* Typer::Visitor::TypeRoundInt64ToFloat64(Node* node) {
return Type::Intersect(Type::PlainNumber(), Type::UntaggedFloat64(), zone()); return Type::Intersect(Type::PlainNumber(), Type::UntaggedFloat64(), zone());
} }
......
...@@ -885,6 +885,7 @@ void Verifier::Visitor::Check(Node* node) { ...@@ -885,6 +885,7 @@ void Verifier::Visitor::Check(Node* node) {
case IrOpcode::kFloat64LessThan: case IrOpcode::kFloat64LessThan:
case IrOpcode::kFloat64LessThanOrEqual: case IrOpcode::kFloat64LessThanOrEqual:
case IrOpcode::kTruncateInt64ToInt32: case IrOpcode::kTruncateInt64ToInt32:
case IrOpcode::kRoundInt64ToFloat32:
case IrOpcode::kRoundInt64ToFloat64: case IrOpcode::kRoundInt64ToFloat64:
case IrOpcode::kTruncateFloat64ToFloat32: case IrOpcode::kTruncateFloat64ToFloat32:
case IrOpcode::kTruncateFloat64ToInt32: case IrOpcode::kTruncateFloat64ToInt32:
......
...@@ -1018,6 +1018,13 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { ...@@ -1018,6 +1018,13 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
__ Cvtlsi2sd(i.OutputDoubleRegister(), i.InputOperand(0)); __ Cvtlsi2sd(i.OutputDoubleRegister(), i.InputOperand(0));
} }
break; break;
case kSSEInt64ToFloat32:
if (instr->InputAt(0)->IsRegister()) {
__ Cvtqsi2ss(i.OutputDoubleRegister(), i.InputRegister(0));
} else {
__ Cvtqsi2ss(i.OutputDoubleRegister(), i.InputOperand(0));
}
break;
case kSSEInt64ToFloat64: case kSSEInt64ToFloat64:
if (instr->InputAt(0)->IsRegister()) { if (instr->InputAt(0)->IsRegister()) {
__ Cvtqsi2sd(i.OutputDoubleRegister(), i.InputRegister(0)); __ Cvtqsi2sd(i.OutputDoubleRegister(), i.InputRegister(0));
......
...@@ -79,6 +79,7 @@ namespace compiler { ...@@ -79,6 +79,7 @@ namespace compiler {
V(SSEFloat64ToInt32) \ V(SSEFloat64ToInt32) \
V(SSEFloat64ToUint32) \ V(SSEFloat64ToUint32) \
V(SSEInt32ToFloat64) \ V(SSEInt32ToFloat64) \
V(SSEInt64ToFloat32) \
V(SSEInt64ToFloat64) \ V(SSEInt64ToFloat64) \
V(SSEUint32ToFloat64) \ V(SSEUint32ToFloat64) \
V(SSEFloat64ExtractLowWord32) \ V(SSEFloat64ExtractLowWord32) \
......
...@@ -959,6 +959,12 @@ void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { ...@@ -959,6 +959,12 @@ void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
} }
void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) {
X64OperandGenerator g(this);
Emit(kSSEInt64ToFloat32, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
}
void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) { void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) {
X64OperandGenerator g(this); X64OperandGenerator g(this);
Emit(kSSEInt64ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0))); Emit(kSSEInt64ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
......
...@@ -3165,6 +3165,28 @@ void Assembler::cvtlsi2ss(XMMRegister dst, Register src) { ...@@ -3165,6 +3165,28 @@ void Assembler::cvtlsi2ss(XMMRegister dst, Register src) {
} }
void Assembler::cvtqsi2ss(XMMRegister dst, const Operand& src) {
DCHECK(!IsEnabled(AVX));
EnsureSpace ensure_space(this);
emit(0xF3);
emit_rex_64(dst, src);
emit(0x0F);
emit(0x2A);
emit_sse_operand(dst, src);
}
void Assembler::cvtqsi2ss(XMMRegister dst, Register src) {
DCHECK(!IsEnabled(AVX));
EnsureSpace ensure_space(this);
emit(0xF3);
emit_rex_64(dst, src);
emit(0x0F);
emit(0x2A);
emit_sse_operand(dst, src);
}
void Assembler::cvtqsi2sd(XMMRegister dst, const Operand& src) { void Assembler::cvtqsi2sd(XMMRegister dst, const Operand& src) {
DCHECK(!IsEnabled(AVX)); DCHECK(!IsEnabled(AVX));
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
......
...@@ -1082,6 +1082,10 @@ class Assembler : public AssemblerBase { ...@@ -1082,6 +1082,10 @@ class Assembler : public AssemblerBase {
void cvtlsi2sd(XMMRegister dst, const Operand& src); void cvtlsi2sd(XMMRegister dst, const Operand& src);
void cvtlsi2sd(XMMRegister dst, Register src); void cvtlsi2sd(XMMRegister dst, Register src);
void cvtqsi2ss(XMMRegister dst, const Operand& src);
void cvtqsi2ss(XMMRegister dst, Register src);
void cvtqsi2sd(XMMRegister dst, const Operand& src); void cvtqsi2sd(XMMRegister dst, const Operand& src);
void cvtqsi2sd(XMMRegister dst, Register src); void cvtqsi2sd(XMMRegister dst, Register src);
...@@ -1363,6 +1367,13 @@ class Assembler : public AssemblerBase { ...@@ -1363,6 +1367,13 @@ class Assembler : public AssemblerBase {
void vcvtlsi2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) { void vcvtlsi2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
vsd(0x2a, dst, src1, src2, kF2, k0F, kW0); vsd(0x2a, dst, src1, src2, kF2, k0F, kW0);
} }
void vcvtqsi2ss(XMMRegister dst, XMMRegister src1, Register src2) {
XMMRegister isrc2 = {src2.code()};
vsd(0x2a, dst, src1, isrc2, kF3, k0F, kW1);
}
void vcvtqsi2ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
vsd(0x2a, dst, src1, src2, kF3, k0F, kW1);
}
void vcvtqsi2sd(XMMRegister dst, XMMRegister src1, Register src2) { void vcvtqsi2sd(XMMRegister dst, XMMRegister src1, Register src2) {
XMMRegister isrc2 = {src2.code()}; XMMRegister isrc2 = {src2.code()};
vsd(0x2a, dst, src1, isrc2, kF2, k0F, kW1); vsd(0x2a, dst, src1, isrc2, kF2, k0F, kW1);
......
...@@ -984,6 +984,11 @@ int DisassemblerX64::AVXInstruction(byte* data) { ...@@ -984,6 +984,11 @@ int DisassemblerX64::AVXInstruction(byte* data) {
} }
AppendToBuffer(",%s", NameOfXMMRegister(regop)); AppendToBuffer(",%s", NameOfXMMRegister(regop));
break; break;
case 0x2a:
AppendToBuffer("%s %s,%s,", vex_w() ? "vcvtqsi2ss" : "vcvtlsi2ss",
NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
current += PrintRightOperand(current);
break;
case 0x58: case 0x58:
AppendToBuffer("vaddss %s,%s,", NameOfXMMRegister(regop), AppendToBuffer("vaddss %s,%s,", NameOfXMMRegister(regop),
NameOfXMMRegister(vvvv)); NameOfXMMRegister(vvvv));
......
...@@ -851,6 +851,30 @@ void MacroAssembler::Cvtlsi2sd(XMMRegister dst, const Operand& src) { ...@@ -851,6 +851,30 @@ void MacroAssembler::Cvtlsi2sd(XMMRegister dst, const Operand& src) {
} }
void MacroAssembler::Cvtqsi2ss(XMMRegister dst, Register src) {
if (CpuFeatures::IsSupported(AVX)) {
CpuFeatureScope scope(this, AVX);
vxorps(dst, dst, dst);
vcvtqsi2ss(dst, dst, src);
} else {
xorps(dst, dst);
cvtqsi2ss(dst, src);
}
}
void MacroAssembler::Cvtqsi2ss(XMMRegister dst, const Operand& src) {
if (CpuFeatures::IsSupported(AVX)) {
CpuFeatureScope scope(this, AVX);
vxorps(dst, dst, dst);
vcvtqsi2ss(dst, dst, src);
} else {
xorps(dst, dst);
cvtqsi2ss(dst, src);
}
}
void MacroAssembler::Cvtqsi2sd(XMMRegister dst, Register src) { void MacroAssembler::Cvtqsi2sd(XMMRegister dst, Register src) {
if (CpuFeatures::IsSupported(AVX)) { if (CpuFeatures::IsSupported(AVX)) {
CpuFeatureScope scope(this, AVX); CpuFeatureScope scope(this, AVX);
......
...@@ -817,6 +817,10 @@ class MacroAssembler: public Assembler { ...@@ -817,6 +817,10 @@ class MacroAssembler: public Assembler {
// xorpd to clear the dst register before cvtsi2sd to solve this issue. // xorpd to clear the dst register before cvtsi2sd to solve this issue.
void Cvtlsi2sd(XMMRegister dst, Register src); void Cvtlsi2sd(XMMRegister dst, Register src);
void Cvtlsi2sd(XMMRegister dst, const Operand& src); void Cvtlsi2sd(XMMRegister dst, const Operand& src);
void Cvtqsi2ss(XMMRegister dst, Register src);
void Cvtqsi2ss(XMMRegister dst, const Operand& src);
void Cvtqsi2sd(XMMRegister dst, Register src); void Cvtqsi2sd(XMMRegister dst, Register src);
void Cvtqsi2sd(XMMRegister dst, const Operand& src); void Cvtqsi2sd(XMMRegister dst, const Operand& src);
......
...@@ -5367,6 +5367,13 @@ TEST(RunBitcastFloat64ToInt64) { ...@@ -5367,6 +5367,13 @@ TEST(RunBitcastFloat64ToInt64) {
} }
TEST(RunRoundInt64ToFloat32) {
BufferedRawMachineAssemblerTester<float> m(kMachInt64);
m.Return(m.RoundInt64ToFloat32(m.Parameter(0)));
FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<float>(*i), m.Call(*i)); }
}
TEST(RunRoundInt64ToFloat64) { TEST(RunRoundInt64ToFloat64) {
BufferedRawMachineAssemblerTester<double> m(kMachInt64); BufferedRawMachineAssemblerTester<double> m(kMachInt64);
m.Return(m.RoundInt64ToFloat64(m.Parameter(0))); m.Return(m.RoundInt64ToFloat64(m.Parameter(0)));
......
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