Commit e06f7d78 authored by ahaas's avatar ahaas Committed by Commit bot

[turbofan] Add the RoundInt32ToFloat32 operator to turbofan.

The new operator converts an int32 input to float32. If the input cannot
be represented exactly in float32, the value is rounded using the
round-ties-even rounding mode (the default rounding mode).

I provide implementations of the new operator for x64, ia32, arm, arm64,
mips, mips64, ppc, and ppc64.

R=titzer@chromium.org, v8-arm-ports@googlegroups.com, v8-mips-ports@googlegroups.com, v8-ppc-ports@googlegroups.com

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

Cr-Commit-Position: refs/heads/master@{#33347}
parent fc53eed1
...@@ -831,6 +831,13 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { ...@@ -831,6 +831,13 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
DCHECK_EQ(LeaveCC, i.OutputSBit()); DCHECK_EQ(LeaveCC, i.OutputSBit());
break; break;
} }
case kArmVcvtF32S32: {
SwVfpRegister scratch = kScratchDoubleReg.low();
__ vmov(scratch, i.InputRegister(0));
__ vcvt_f32_s32(i.OutputFloat32Register(), scratch);
DCHECK_EQ(LeaveCC, i.OutputSBit());
break;
}
case kArmVcvtF64S32: { case kArmVcvtF64S32: {
SwVfpRegister scratch = kScratchDoubleReg.low(); SwVfpRegister scratch = kScratchDoubleReg.low();
__ vmov(scratch, i.InputRegister(0)); __ vmov(scratch, i.InputRegister(0));
......
...@@ -76,6 +76,7 @@ namespace compiler { ...@@ -76,6 +76,7 @@ namespace compiler {
V(ArmVrintnF64) \ V(ArmVrintnF64) \
V(ArmVcvtF32F64) \ V(ArmVcvtF32F64) \
V(ArmVcvtF64F32) \ V(ArmVcvtF64F32) \
V(ArmVcvtF32S32) \
V(ArmVcvtF64S32) \ V(ArmVcvtF64S32) \
V(ArmVcvtF64U32) \ V(ArmVcvtF64U32) \
V(ArmVcvtS32F32) \ V(ArmVcvtS32F32) \
......
...@@ -78,6 +78,7 @@ int InstructionScheduler::GetTargetInstructionFlags( ...@@ -78,6 +78,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kArmVrintnF64: case kArmVrintnF64:
case kArmVcvtF32F64: case kArmVcvtF32F64:
case kArmVcvtF64F32: case kArmVcvtF64F32:
case kArmVcvtF32S32:
case kArmVcvtF64S32: case kArmVcvtF64S32:
case kArmVcvtF64U32: case kArmVcvtF64U32:
case kArmVcvtS32F32: case kArmVcvtS32F32:
......
...@@ -921,6 +921,11 @@ void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { ...@@ -921,6 +921,11 @@ void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
} }
void InstructionSelector::VisitRoundInt32ToFloat32(Node* node) {
VisitRR(this, kArmVcvtF32S32, node);
}
void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
VisitRR(this, kArmVcvtF64S32, node); VisitRR(this, kArmVcvtF64S32, node);
} }
......
...@@ -1096,6 +1096,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { ...@@ -1096,6 +1096,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
__ Cset(i.OutputRegister(1), ne); __ Cset(i.OutputRegister(1), ne);
} }
break; break;
case kArm64Int32ToFloat32:
__ Scvtf(i.OutputFloat32Register(), i.InputRegister32(0));
break;
case kArm64Int32ToFloat64: case kArm64Int32ToFloat64:
__ Scvtf(i.OutputDoubleRegister(), i.InputRegister32(0)); __ Scvtf(i.OutputDoubleRegister(), i.InputRegister32(0));
break; break;
......
...@@ -117,6 +117,7 @@ namespace compiler { ...@@ -117,6 +117,7 @@ namespace compiler {
V(Arm64Float64ToInt64) \ V(Arm64Float64ToInt64) \
V(Arm64Float32ToUint64) \ V(Arm64Float32ToUint64) \
V(Arm64Float64ToUint64) \ V(Arm64Float64ToUint64) \
V(Arm64Int32ToFloat32) \
V(Arm64Int32ToFloat64) \ V(Arm64Int32ToFloat64) \
V(Arm64Int64ToFloat32) \ V(Arm64Int64ToFloat32) \
V(Arm64Int64ToFloat64) \ V(Arm64Int64ToFloat64) \
......
...@@ -113,6 +113,7 @@ int InstructionScheduler::GetTargetInstructionFlags( ...@@ -113,6 +113,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kArm64Float64ToInt64: case kArm64Float64ToInt64:
case kArm64Float32ToUint64: case kArm64Float32ToUint64:
case kArm64Float64ToUint64: case kArm64Float64ToUint64:
case kArm64Int32ToFloat32:
case kArm64Int32ToFloat64: case kArm64Int32ToFloat64:
case kArm64Int64ToFloat32: case kArm64Int64ToFloat32:
case kArm64Int64ToFloat64: case kArm64Int64ToFloat64:
......
...@@ -1219,6 +1219,11 @@ void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { ...@@ -1219,6 +1219,11 @@ void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
} }
void InstructionSelector::VisitRoundInt32ToFloat32(Node* node) {
VisitRR(this, kArm64Int32ToFloat32, node);
}
void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
VisitRR(this, kArm64Int32ToFloat64, node); VisitRR(this, kArm64Int32ToFloat64, node);
} }
......
...@@ -752,6 +752,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { ...@@ -752,6 +752,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
__ add(i.OutputRegister(), Immediate(0x80000000)); __ add(i.OutputRegister(), Immediate(0x80000000));
break; break;
} }
case kSSEInt32ToFloat32:
__ cvtsi2ss(i.OutputDoubleRegister(), i.InputOperand(0));
break;
case kSSEInt32ToFloat64: case kSSEInt32ToFloat64:
__ cvtsi2sd(i.OutputDoubleRegister(), i.InputOperand(0)); __ cvtsi2sd(i.OutputDoubleRegister(), i.InputOperand(0));
break; break;
......
...@@ -61,6 +61,7 @@ namespace compiler { ...@@ -61,6 +61,7 @@ namespace compiler {
V(SSEFloat32ToInt32) \ V(SSEFloat32ToInt32) \
V(SSEFloat64ToInt32) \ V(SSEFloat64ToInt32) \
V(SSEFloat64ToUint32) \ V(SSEFloat64ToUint32) \
V(SSEInt32ToFloat32) \
V(SSEInt32ToFloat64) \ V(SSEInt32ToFloat64) \
V(SSEUint32ToFloat64) \ V(SSEUint32ToFloat64) \
V(SSEFloat64ExtractLowWord32) \ V(SSEFloat64ExtractLowWord32) \
......
...@@ -64,6 +64,7 @@ int InstructionScheduler::GetTargetInstructionFlags( ...@@ -64,6 +64,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kSSEFloat32ToInt32: case kSSEFloat32ToInt32:
case kSSEFloat64ToInt32: case kSSEFloat64ToInt32:
case kSSEFloat64ToUint32: case kSSEFloat64ToUint32:
case kSSEInt32ToFloat32:
case kSSEInt32ToFloat64: case kSSEInt32ToFloat64:
case kSSEUint32ToFloat64: case kSSEUint32ToFloat64:
case kSSEFloat64ExtractLowWord32: case kSSEFloat64ExtractLowWord32:
......
...@@ -695,6 +695,11 @@ void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { ...@@ -695,6 +695,11 @@ void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
} }
void InstructionSelector::VisitRoundInt32ToFloat32(Node* node) {
VisitRO(this, node, kSSEInt32ToFloat32);
}
void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
VisitRO(this, node, kSSEInt32ToFloat64); VisitRO(this, node, kSSEInt32ToFloat64);
} }
......
...@@ -978,6 +978,8 @@ void InstructionSelector::VisitNode(Node* node) { ...@@ -978,6 +978,8 @@ void InstructionSelector::VisitNode(Node* node) {
return MarkAsWord32(node), VisitTruncateInt64ToInt32(node); return MarkAsWord32(node), VisitTruncateInt64ToInt32(node);
case IrOpcode::kRoundInt64ToFloat32: case IrOpcode::kRoundInt64ToFloat32:
return MarkAsFloat32(node), VisitRoundInt64ToFloat32(node); return MarkAsFloat32(node), VisitRoundInt64ToFloat32(node);
case IrOpcode::kRoundInt32ToFloat32:
return MarkAsFloat32(node), VisitRoundInt32ToFloat32(node);
case IrOpcode::kRoundInt64ToFloat64: case IrOpcode::kRoundInt64ToFloat64:
return MarkAsFloat64(node), VisitRoundInt64ToFloat64(node); return MarkAsFloat64(node), VisitRoundInt64ToFloat64(node);
case IrOpcode::kBitcastFloat32ToInt32: case IrOpcode::kBitcastFloat32ToInt32:
......
...@@ -150,6 +150,7 @@ CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) { ...@@ -150,6 +150,7 @@ CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) {
V(TryTruncateFloat32ToUint64, Operator::kNoProperties, 1, 0, 2) \ V(TryTruncateFloat32ToUint64, Operator::kNoProperties, 1, 0, 2) \
V(TryTruncateFloat64ToUint64, Operator::kNoProperties, 1, 0, 2) \ V(TryTruncateFloat64ToUint64, Operator::kNoProperties, 1, 0, 2) \
V(ChangeInt32ToFloat64, Operator::kNoProperties, 1, 0, 1) \ V(ChangeInt32ToFloat64, Operator::kNoProperties, 1, 0, 1) \
V(RoundInt32ToFloat32, Operator::kNoProperties, 1, 0, 1) \
V(RoundInt64ToFloat32, 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(RoundUint64ToFloat32, Operator::kNoProperties, 1, 0, 1) \ V(RoundUint64ToFloat32, Operator::kNoProperties, 1, 0, 1) \
......
...@@ -228,6 +228,7 @@ class MachineOperatorBuilder final : public ZoneObject { ...@@ -228,6 +228,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* RoundInt32ToFloat32();
const Operator* RoundInt64ToFloat32(); const Operator* RoundInt64ToFloat32();
const Operator* RoundInt64ToFloat64(); const Operator* RoundInt64ToFloat64();
const Operator* RoundUint64ToFloat32(); const Operator* RoundUint64ToFloat32();
......
...@@ -503,6 +503,11 @@ void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { ...@@ -503,6 +503,11 @@ void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
} }
void InstructionSelector::VisitRoundInt32ToFloat32(Node* node) {
VisitRR(this, kMipsCvtSW, node);
}
void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
VisitRR(this, kMipsCvtDW, node); VisitRR(this, kMipsCvtDW, node);
} }
......
...@@ -802,6 +802,11 @@ void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { ...@@ -802,6 +802,11 @@ void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
} }
void InstructionSelector::VisitRoundInt32ToFloat32(Node* node) {
VisitRR(this, kMips64CvtSW, node);
}
void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
VisitRR(this, kMips64CvtDW, node); VisitRR(this, kMips64CvtDW, node);
} }
......
...@@ -282,6 +282,7 @@ ...@@ -282,6 +282,7 @@
V(TruncateFloat64ToFloat32) \ V(TruncateFloat64ToFloat32) \
V(TruncateFloat64ToInt32) \ V(TruncateFloat64ToInt32) \
V(TruncateInt64ToInt32) \ V(TruncateInt64ToInt32) \
V(RoundInt32ToFloat32) \
V(RoundInt64ToFloat32) \ V(RoundInt64ToFloat32) \
V(RoundInt64ToFloat64) \ V(RoundInt64ToFloat64) \
V(RoundUint64ToFloat32) \ V(RoundUint64ToFloat32) \
......
...@@ -1194,6 +1194,11 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { ...@@ -1194,6 +1194,11 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
DCHECK_EQ(LeaveRC, i.OutputRCBit()); DCHECK_EQ(LeaveRC, i.OutputRCBit());
break; break;
#endif #endif
case kPPC_Int32ToFloat32:
__ ConvertIntToFloat(i.OutputDoubleRegister(), i.InputRegister(0),
kScratchReg);
DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
case kPPC_Int32ToDouble: case kPPC_Int32ToDouble:
__ ConvertIntToDouble(i.InputRegister(0), i.OutputDoubleRegister()); __ ConvertIntToDouble(i.InputRegister(0), i.OutputDoubleRegister());
DCHECK_EQ(LeaveRC, i.OutputRCBit()); DCHECK_EQ(LeaveRC, i.OutputRCBit());
......
...@@ -82,6 +82,7 @@ namespace compiler { ...@@ -82,6 +82,7 @@ namespace compiler {
V(PPC_Int64ToDouble) \ V(PPC_Int64ToDouble) \
V(PPC_Uint64ToFloat32) \ V(PPC_Uint64ToFloat32) \
V(PPC_Uint64ToDouble) \ V(PPC_Uint64ToDouble) \
V(PPC_Int32ToFloat32) \
V(PPC_Int32ToDouble) \ V(PPC_Int32ToDouble) \
V(PPC_Uint32ToDouble) \ V(PPC_Uint32ToDouble) \
V(PPC_Float32ToDouble) \ V(PPC_Float32ToDouble) \
......
...@@ -81,6 +81,7 @@ int InstructionScheduler::GetTargetInstructionFlags( ...@@ -81,6 +81,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kPPC_Int64ToDouble: case kPPC_Int64ToDouble:
case kPPC_Uint64ToFloat32: case kPPC_Uint64ToFloat32:
case kPPC_Uint64ToDouble: case kPPC_Uint64ToDouble:
case kPPC_Int32ToFloat32:
case kPPC_Int32ToDouble: case kPPC_Int32ToDouble:
case kPPC_Uint32ToDouble: case kPPC_Uint32ToDouble:
case kPPC_Float32ToDouble: case kPPC_Float32ToDouble:
......
...@@ -940,6 +940,11 @@ void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { ...@@ -940,6 +940,11 @@ void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
} }
void InstructionSelector::VisitRoundInt32ToFloat32(Node* node) {
VisitRR(this, kPPC_Int32ToFloat32, node);
}
void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
VisitRR(this, kPPC_Int32ToDouble, node); VisitRR(this, kPPC_Int32ToDouble, node);
} }
......
...@@ -472,6 +472,9 @@ class RawMachineAssembler { ...@@ -472,6 +472,9 @@ class RawMachineAssembler {
Node* TruncateInt64ToInt32(Node* a) { Node* TruncateInt64ToInt32(Node* a) {
return AddNode(machine()->TruncateInt64ToInt32(), a); return AddNode(machine()->TruncateInt64ToInt32(), a);
} }
Node* RoundInt32ToFloat32(Node* a) {
return AddNode(machine()->RoundInt32ToFloat32(), a);
}
Node* RoundInt64ToFloat32(Node* a) { Node* RoundInt64ToFloat32(Node* a) {
return AddNode(machine()->RoundInt64ToFloat32(), a); return AddNode(machine()->RoundInt64ToFloat32(), a);
} }
......
...@@ -2205,6 +2205,11 @@ Type* Typer::Visitor::TypeTruncateInt64ToInt32(Node* node) { ...@@ -2205,6 +2205,11 @@ Type* Typer::Visitor::TypeTruncateInt64ToInt32(Node* node) {
} }
Type* Typer::Visitor::TypeRoundInt32ToFloat32(Node* node) {
return Type::Intersect(Type::PlainNumber(), Type::UntaggedFloat32(), zone());
}
Type* Typer::Visitor::TypeRoundInt64ToFloat32(Node* node) { Type* Typer::Visitor::TypeRoundInt64ToFloat32(Node* node) {
return Type::Intersect(Type::PlainNumber(), Type::UntaggedFloat32(), zone()); return Type::Intersect(Type::PlainNumber(), Type::UntaggedFloat32(), zone());
} }
......
...@@ -907,6 +907,7 @@ void Verifier::Visitor::Check(Node* node) { ...@@ -907,6 +907,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::kRoundInt32ToFloat32:
case IrOpcode::kRoundInt64ToFloat32: case IrOpcode::kRoundInt64ToFloat32:
case IrOpcode::kRoundInt64ToFloat64: case IrOpcode::kRoundInt64ToFloat64:
case IrOpcode::kRoundUint64ToFloat64: case IrOpcode::kRoundUint64ToFloat64:
......
...@@ -696,9 +696,7 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) { ...@@ -696,9 +696,7 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) {
op = m->ChangeUint32ToFloat64(); op = m->ChangeUint32ToFloat64();
break; break;
case wasm::kExprF32SConvertI32: case wasm::kExprF32SConvertI32:
op = m->ChangeInt32ToFloat64(); // TODO(titzer): two conversions op = m->RoundInt32ToFloat32();
input = graph()->NewNode(op, input);
op = m->TruncateFloat64ToFloat32();
break; break;
case wasm::kExprF32UConvertI32: case wasm::kExprF32UConvertI32:
op = m->ChangeUint32ToFloat64(); op = m->ChangeUint32ToFloat64();
......
...@@ -1204,6 +1204,13 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { ...@@ -1204,6 +1204,13 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
__ Cvtlsi2sd(i.OutputDoubleRegister(), i.InputOperand(0)); __ Cvtlsi2sd(i.OutputDoubleRegister(), i.InputOperand(0));
} }
break; break;
case kSSEInt32ToFloat32:
if (instr->InputAt(0)->IsRegister()) {
__ Cvtlsi2ss(i.OutputDoubleRegister(), i.InputRegister(0));
} else {
__ Cvtlsi2ss(i.OutputDoubleRegister(), i.InputOperand(0));
}
break;
case kSSEInt64ToFloat32: case kSSEInt64ToFloat32:
if (instr->InputAt(0)->IsRegister()) { if (instr->InputAt(0)->IsRegister()) {
__ Cvtqsi2ss(i.OutputDoubleRegister(), i.InputRegister(0)); __ Cvtqsi2ss(i.OutputDoubleRegister(), i.InputRegister(0));
......
...@@ -85,6 +85,7 @@ namespace compiler { ...@@ -85,6 +85,7 @@ namespace compiler {
V(SSEFloat32ToUint64) \ V(SSEFloat32ToUint64) \
V(SSEFloat64ToUint64) \ V(SSEFloat64ToUint64) \
V(SSEInt32ToFloat64) \ V(SSEInt32ToFloat64) \
V(SSEInt32ToFloat32) \
V(SSEInt64ToFloat32) \ V(SSEInt64ToFloat32) \
V(SSEInt64ToFloat64) \ V(SSEInt64ToFloat64) \
V(SSEUint64ToFloat32) \ V(SSEUint64ToFloat32) \
......
...@@ -87,6 +87,7 @@ int InstructionScheduler::GetTargetInstructionFlags( ...@@ -87,6 +87,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kSSEFloat64ToUint64: case kSSEFloat64ToUint64:
case kSSEFloat32ToUint64: case kSSEFloat32ToUint64:
case kSSEInt32ToFloat64: case kSSEInt32ToFloat64:
case kSSEInt32ToFloat32:
case kSSEInt64ToFloat32: case kSSEInt64ToFloat32:
case kSSEInt64ToFloat64: case kSSEInt64ToFloat64:
case kSSEUint64ToFloat32: case kSSEUint64ToFloat32:
......
...@@ -1052,6 +1052,12 @@ void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { ...@@ -1052,6 +1052,12 @@ void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
} }
void InstructionSelector::VisitRoundInt32ToFloat32(Node* node) {
X64OperandGenerator g(this);
Emit(kSSEInt32ToFloat32, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
}
void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) { void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) {
X64OperandGenerator g(this); X64OperandGenerator g(this);
Emit(kSSEInt64ToFloat32, g.DefineAsRegister(node), g.Use(node->InputAt(0))); Emit(kSSEInt64ToFloat32, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
......
...@@ -655,6 +655,11 @@ void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { ...@@ -655,6 +655,11 @@ void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
} }
void InstructionSelector::VisitRoundInt32ToFloat32(Node* node) {
UNIMPLEMENTED();
}
void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
X87OperandGenerator g(this); X87OperandGenerator g(this);
Emit(kX87Int32ToFloat64, g.DefineAsFixed(node, stX_0), Emit(kX87Int32ToFloat64, g.DefineAsFixed(node, stX_0),
......
...@@ -2000,6 +2000,15 @@ void Assembler::cvtsd2si(Register dst, XMMRegister src) { ...@@ -2000,6 +2000,15 @@ void Assembler::cvtsd2si(Register dst, XMMRegister src) {
} }
void Assembler::cvtsi2ss(XMMRegister dst, const Operand& src) {
EnsureSpace ensure_space(this);
EMIT(0xF3);
EMIT(0x0F);
EMIT(0x2A);
emit_sse_operand(dst, src);
}
void Assembler::cvtsi2sd(XMMRegister dst, const Operand& src) { void Assembler::cvtsi2sd(XMMRegister dst, const Operand& src) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
EMIT(0xF2); EMIT(0xF2);
......
...@@ -960,6 +960,8 @@ class Assembler : public AssemblerBase { ...@@ -960,6 +960,8 @@ class Assembler : public AssemblerBase {
} }
void cvtsd2si(Register dst, XMMRegister src); void cvtsd2si(Register dst, XMMRegister src);
void cvtsi2ss(XMMRegister dst, Register src) { cvtsi2ss(dst, Operand(src)); }
void cvtsi2ss(XMMRegister dst, const Operand& src);
void cvtsi2sd(XMMRegister dst, Register src) { cvtsi2sd(dst, Operand(src)); } void cvtsi2sd(XMMRegister dst, Register src) { cvtsi2sd(dst, Operand(src)); }
void cvtsi2sd(XMMRegister dst, const Operand& src); void cvtsi2sd(XMMRegister dst, const Operand& src);
void cvtss2sd(XMMRegister dst, const Operand& src); void cvtss2sd(XMMRegister dst, const Operand& src);
......
...@@ -3179,6 +3179,17 @@ void Assembler::cvtlsi2sd(XMMRegister dst, Register src) { ...@@ -3179,6 +3179,17 @@ void Assembler::cvtlsi2sd(XMMRegister dst, Register src) {
} }
void Assembler::cvtlsi2ss(XMMRegister dst, const Operand& src) {
DCHECK(!IsEnabled(AVX));
EnsureSpace ensure_space(this);
emit(0xF3);
emit_optional_rex_32(dst, src);
emit(0x0F);
emit(0x2A);
emit_sse_operand(dst, src);
}
void Assembler::cvtlsi2ss(XMMRegister dst, Register src) { void Assembler::cvtlsi2ss(XMMRegister dst, Register src) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
emit(0xF3); emit(0xF3);
......
...@@ -1025,6 +1025,7 @@ class Assembler : public AssemblerBase { ...@@ -1025,6 +1025,7 @@ class Assembler : public AssemblerBase {
void cvttss2si(Register dst, const Operand& src); void cvttss2si(Register dst, const Operand& src);
void cvttss2si(Register dst, XMMRegister src); void cvttss2si(Register dst, XMMRegister src);
void cvtlsi2ss(XMMRegister dst, const Operand& src);
void cvtlsi2ss(XMMRegister dst, Register src); void cvtlsi2ss(XMMRegister dst, Register src);
void andps(XMMRegister dst, XMMRegister src); void andps(XMMRegister dst, XMMRegister src);
...@@ -1370,6 +1371,13 @@ class Assembler : public AssemblerBase { ...@@ -1370,6 +1371,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 vcvtlsi2ss(XMMRegister dst, XMMRegister src1, Register src2) {
XMMRegister isrc2 = {src2.code()};
vsd(0x2a, dst, src1, isrc2, kF3, k0F, kW0);
}
void vcvtlsi2ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
vsd(0x2a, dst, src1, src2, kF3, k0F, kW0);
}
void vcvtqsi2ss(XMMRegister dst, XMMRegister src1, Register src2) { void vcvtqsi2ss(XMMRegister dst, XMMRegister src1, Register src2) {
XMMRegister isrc2 = {src2.code()}; XMMRegister isrc2 = {src2.code()};
vsd(0x2a, dst, src1, isrc2, kF3, k0F, kW1); vsd(0x2a, dst, src1, isrc2, kF3, k0F, kW1);
......
...@@ -823,6 +823,30 @@ void MacroAssembler::Cvtlsi2sd(XMMRegister dst, const Operand& src) { ...@@ -823,6 +823,30 @@ void MacroAssembler::Cvtlsi2sd(XMMRegister dst, const Operand& src) {
} }
void MacroAssembler::Cvtlsi2ss(XMMRegister dst, Register src) {
if (CpuFeatures::IsSupported(AVX)) {
CpuFeatureScope scope(this, AVX);
vxorps(dst, dst, dst);
vcvtlsi2ss(dst, dst, src);
} else {
xorps(dst, dst);
cvtlsi2ss(dst, src);
}
}
void MacroAssembler::Cvtlsi2ss(XMMRegister dst, const Operand& src) {
if (CpuFeatures::IsSupported(AVX)) {
CpuFeatureScope scope(this, AVX);
vxorps(dst, dst, dst);
vcvtlsi2ss(dst, dst, src);
} else {
xorps(dst, dst);
cvtlsi2ss(dst, src);
}
}
void MacroAssembler::Cvtqsi2ss(XMMRegister dst, Register src) { void MacroAssembler::Cvtqsi2ss(XMMRegister dst, Register src) {
if (CpuFeatures::IsSupported(AVX)) { if (CpuFeatures::IsSupported(AVX)) {
CpuFeatureScope scope(this, AVX); CpuFeatureScope scope(this, AVX);
......
...@@ -812,6 +812,8 @@ class MacroAssembler: public Assembler { ...@@ -812,6 +812,8 @@ class MacroAssembler: public Assembler {
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 Cvtlsi2ss(XMMRegister dst, Register src);
void Cvtlsi2ss(XMMRegister dst, const Operand& src);
void Cvtqsi2ss(XMMRegister dst, Register src); void Cvtqsi2ss(XMMRegister dst, Register src);
void Cvtqsi2ss(XMMRegister dst, const Operand& src); void Cvtqsi2ss(XMMRegister dst, const Operand& src);
......
...@@ -6013,6 +6013,13 @@ TEST(RunBitcastFloat32ToInt32) { ...@@ -6013,6 +6013,13 @@ TEST(RunBitcastFloat32ToInt32) {
} }
TEST(RunRoundInt32ToFloat32) {
BufferedRawMachineAssemblerTester<float> m(MachineType::Int32());
m.Return(m.RoundInt32ToFloat32(m.Parameter(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(static_cast<float>(*i), m.Call(*i)); }
}
TEST(RunBitcastInt32ToFloat32) { TEST(RunBitcastInt32ToFloat32) {
int32_t input = 1; int32_t input = 1;
float output = 0.0; float output = 0.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