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