From 3396c2badd9e6f4ab693ccd67d25c31f5f9a4b4d Mon Sep 17 00:00:00 2001 From: "dcarney@chromium.org" Date: Mon, 13 Oct 2014 07:12:57 +0000 Subject: [PATCH] [turbofan] IA: TruncateFloat64ToFloat32 supports mem operand BUG= R=dcarney@chromium.org Review URL: https://codereview.chromium.org/639283003 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24541 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/compiler/ia32/code-generator-ia32.cc | 2 +- src/compiler/ia32/instruction-selector-ia32.cc | 3 +-- src/compiler/x64/code-generator-x64.cc | 6 ++++- src/compiler/x64/instruction-selector-x64.cc | 3 +-- src/ia32/assembler-ia32.cc | 2 +- src/ia32/assembler-ia32.h | 5 +++- src/x64/assembler-x64.cc | 10 ++++++++ src/x64/assembler-x64.h | 1 + test/cctest/compiler/test-run-machops.cc | 32 ++++++++++++++++++++++++++ test/cctest/test-disasm-ia32.cc | 2 ++ test/cctest/test-disasm-x64.cc | 2 ++ 11 files changed, 60 insertions(+), 8 deletions(-) diff --git a/src/compiler/ia32/code-generator-ia32.cc b/src/compiler/ia32/code-generator-ia32.cc index 0c71bf3..7d83e71 100644 --- a/src/compiler/ia32/code-generator-ia32.cc +++ b/src/compiler/ia32/code-generator-ia32.cc @@ -354,7 +354,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { __ cvtss2sd(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); break; case kSSECvtsd2ss: - __ cvtsd2ss(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); + __ cvtsd2ss(i.OutputDoubleRegister(), i.InputOperand(0)); break; case kSSEFloat64ToInt32: __ cvttsd2si(i.OutputRegister(), i.InputOperand(0)); diff --git a/src/compiler/ia32/instruction-selector-ia32.cc b/src/compiler/ia32/instruction-selector-ia32.cc index dee53c9..d973c0f 100644 --- a/src/compiler/ia32/instruction-selector-ia32.cc +++ b/src/compiler/ia32/instruction-selector-ia32.cc @@ -530,8 +530,7 @@ void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) { void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) { IA32OperandGenerator g(this); - // TODO(turbofan): IA32 SSE conversions should take an operand. - Emit(kSSECvtsd2ss, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0))); + Emit(kSSECvtsd2ss, g.DefineAsRegister(node), g.Use(node->InputAt(0))); } diff --git a/src/compiler/x64/code-generator-x64.cc b/src/compiler/x64/code-generator-x64.cc index de8956e..ebd3d9a 100644 --- a/src/compiler/x64/code-generator-x64.cc +++ b/src/compiler/x64/code-generator-x64.cc @@ -408,7 +408,11 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { __ cvtss2sd(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); break; case kSSECvtsd2ss: - __ cvtsd2ss(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); + if (instr->InputAt(0)->IsDoubleRegister()) { + __ cvtsd2ss(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); + } else { + __ cvtsd2ss(i.OutputDoubleRegister(), i.InputOperand(0)); + } break; case kSSEFloat64ToInt32: if (instr->InputAt(0)->IsDoubleRegister()) { diff --git a/src/compiler/x64/instruction-selector-x64.cc b/src/compiler/x64/instruction-selector-x64.cc index 7f9e40a..33d58fc 100644 --- a/src/compiler/x64/instruction-selector-x64.cc +++ b/src/compiler/x64/instruction-selector-x64.cc @@ -651,8 +651,7 @@ void InstructionSelector::VisitChangeUint32ToUint64(Node* node) { void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) { X64OperandGenerator g(this); - // TODO(turbofan): X64 SSE conversions should take an operand. - Emit(kSSECvtsd2ss, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0))); + Emit(kSSECvtsd2ss, g.DefineAsRegister(node), g.Use(node->InputAt(0))); } diff --git a/src/ia32/assembler-ia32.cc b/src/ia32/assembler-ia32.cc index 7a9b963..10bf608 100644 --- a/src/ia32/assembler-ia32.cc +++ b/src/ia32/assembler-ia32.cc @@ -1960,7 +1960,7 @@ void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) { } -void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) { +void Assembler::cvtsd2ss(XMMRegister dst, const Operand& src) { EnsureSpace ensure_space(this); EMIT(0xF2); EMIT(0x0F); diff --git a/src/ia32/assembler-ia32.h b/src/ia32/assembler-ia32.h index 3cab0e4..960ed30 100644 --- a/src/ia32/assembler-ia32.h +++ b/src/ia32/assembler-ia32.h @@ -959,7 +959,10 @@ class Assembler : public AssemblerBase { void cvtsi2sd(XMMRegister dst, Register src) { cvtsi2sd(dst, Operand(src)); } void cvtsi2sd(XMMRegister dst, const Operand& src); void cvtss2sd(XMMRegister dst, XMMRegister src); - void cvtsd2ss(XMMRegister dst, XMMRegister src); + void cvtsd2ss(XMMRegister dst, const Operand& src); + void cvtsd2ss(XMMRegister dst, XMMRegister src) { + cvtsd2ss(dst, Operand(src)); + } void addsd(XMMRegister dst, XMMRegister src); void addsd(XMMRegister dst, const Operand& src); diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc index 01103b2..6e44253 100644 --- a/src/x64/assembler-x64.cc +++ b/src/x64/assembler-x64.cc @@ -2761,6 +2761,16 @@ void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) { } +void Assembler::cvtsd2ss(XMMRegister dst, const Operand& src) { + EnsureSpace ensure_space(this); + emit(0xF2); + emit_optional_rex_32(dst, src); + emit(0x0F); + emit(0x5A); + emit_sse_operand(dst, src); +} + + void Assembler::cvtsd2si(Register dst, XMMRegister src) { EnsureSpace ensure_space(this); emit(0xF2); diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h index b461124..aebad60 100644 --- a/src/x64/assembler-x64.h +++ b/src/x64/assembler-x64.h @@ -1076,6 +1076,7 @@ class Assembler : public AssemblerBase { void cvtss2sd(XMMRegister dst, XMMRegister src); void cvtss2sd(XMMRegister dst, const Operand& src); void cvtsd2ss(XMMRegister dst, XMMRegister src); + void cvtsd2ss(XMMRegister dst, const Operand& src); void cvtsd2si(Register dst, XMMRegister src); void cvtsd2siq(Register dst, XMMRegister src); diff --git a/test/cctest/compiler/test-run-machops.cc b/test/cctest/compiler/test-run-machops.cc index 55a8ae7..1c1c7ea 100644 --- a/test/cctest/compiler/test-run-machops.cc +++ b/test/cctest/compiler/test-run-machops.cc @@ -3320,6 +3320,38 @@ TEST(RunChangeFloat64ToUint32_spilled) { } +TEST(RunTruncateFloat64ToFloat32_spilled) { + RawMachineAssemblerTester m; + const int kNumInputs = 32; + int32_t magic = 0x786234; + double input[kNumInputs]; + float result[kNumInputs]; + Node* input_node[kNumInputs]; + + for (int i = 0; i < kNumInputs; i++) { + input_node[i] = + m.Load(kMachFloat64, m.PointerConstant(&input), m.Int32Constant(i * 8)); + } + + for (int i = 0; i < kNumInputs; i++) { + m.Store(kMachFloat32, m.PointerConstant(&result), m.Int32Constant(i * 4), + m.TruncateFloat64ToFloat32(input_node[i])); + } + + m.Return(m.Int32Constant(magic)); + + for (int i = 0; i < kNumInputs; i++) { + input[i] = 0.1 + i; + } + + CHECK_EQ(magic, m.Call()); + + for (int i = 0; i < kNumInputs; i++) { + CHECK_EQ(result[i], DoubleToFloat32(input[i])); + } +} + + TEST(RunDeadChangeFloat64ToInt32) { RawMachineAssemblerTester m; const int magic = 0x88abcda4; diff --git a/test/cctest/test-disasm-ia32.cc b/test/cctest/test-disasm-ia32.cc index 8615d86..a85d57d 100644 --- a/test/cctest/test-disasm-ia32.cc +++ b/test/cctest/test-disasm-ia32.cc @@ -389,6 +389,8 @@ TEST(DisasmIa320) { // Move operation __ movaps(xmm0, xmm1); __ shufps(xmm0, xmm0, 0x0); + __ cvtsd2ss(xmm0, xmm1); + __ cvtsd2ss(xmm0, Operand(ebx, ecx, times_4, 10000)); // logic operation __ andps(xmm0, xmm1); diff --git a/test/cctest/test-disasm-x64.cc b/test/cctest/test-disasm-x64.cc index 0a4882e..0c600c2 100644 --- a/test/cctest/test-disasm-x64.cc +++ b/test/cctest/test-disasm-x64.cc @@ -380,6 +380,8 @@ TEST(DisasmX64) { // Move operation __ cvttss2si(rdx, Operand(rbx, rcx, times_4, 10000)); __ cvttss2si(rdx, xmm1); + __ cvtsd2ss(xmm0, xmm1); + __ cvtsd2ss(xmm0, Operand(rbx, rcx, times_4, 10000)); __ movaps(xmm0, xmm1); // logic operation -- 2.7.4