From 8c3af6ca03ffa8f61608614dc1c316d885a09801 Mon Sep 17 00:00:00 2001 From: "balazs.kilvady" Date: Wed, 8 Apr 2015 12:30:04 -0700 Subject: [PATCH] MIPS: [turbofan] Add new Float32Abs and Float64Abs operators. Port 9af9f1d0262e2dab66c62331a03f6a76504f3866 Original commit message: These operators compute the absolute floating point value of some arbitrary input, and are implemented without any branches (i.e. using vabs on arm, and andps/andpd on x86). BUG= Review URL: https://codereview.chromium.org/1073463003 Cr-Commit-Position: refs/heads/master@{#27679} --- src/compiler/mips/code-generator-mips.cc | 6 ++++ src/compiler/mips/instruction-codes-mips.h | 2 ++ .../mips/instruction-selector-mips.cc | 17 +++++++---- src/compiler/mips64/code-generator-mips64.cc | 6 ++++ .../mips64/instruction-codes-mips64.h | 2 ++ .../mips64/instruction-selector-mips64.cc | 12 ++++++-- src/mips/assembler-mips.cc | 5 ++++ src/mips/assembler-mips.h | 1 + src/mips64/assembler-mips64.cc | 5 ++++ src/mips64/assembler-mips64.h | 1 + .../instruction-selector-mips-unittest.cc | 30 +++++++++++++++++++ .../instruction-selector-mips64-unittest.cc | 30 +++++++++++++++++++ 12 files changed, 109 insertions(+), 8 deletions(-) diff --git a/src/compiler/mips/code-generator-mips.cc b/src/compiler/mips/code-generator-mips.cc index 4247a84c5..ec545156e 100644 --- a/src/compiler/mips/code-generator-mips.cc +++ b/src/compiler/mips/code-generator-mips.cc @@ -577,6 +577,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { __ MovFromFloatResult(i.OutputSingleRegister()); break; } + case kMipsAbsS: + __ abs_s(i.OutputSingleRegister(), i.InputSingleRegister(0)); + break; case kMipsSqrtS: { __ sqrt_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); break; @@ -615,6 +618,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { __ MovFromFloatResult(i.OutputDoubleRegister()); break; } + case kMipsAbsD: + __ abs_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); + break; case kMipsSqrtD: { __ sqrt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); break; diff --git a/src/compiler/mips/instruction-codes-mips.h b/src/compiler/mips/instruction-codes-mips.h index d40cf14d4..372b41462 100644 --- a/src/compiler/mips/instruction-codes-mips.h +++ b/src/compiler/mips/instruction-codes-mips.h @@ -40,6 +40,7 @@ namespace compiler { V(MipsMulS) \ V(MipsDivS) \ V(MipsModS) \ + V(MipsAbsS) \ V(MipsSqrtS) \ V(MipsCmpD) \ V(MipsAddD) \ @@ -47,6 +48,7 @@ namespace compiler { V(MipsMulD) \ V(MipsDivD) \ V(MipsModD) \ + V(MipsAbsD) \ V(MipsSqrtD) \ V(MipsFloat64RoundDown) \ V(MipsFloat64RoundTruncate) \ diff --git a/src/compiler/mips/instruction-selector-mips.cc b/src/compiler/mips/instruction-selector-mips.cc index 61a5a1cfc..28e030fa1 100644 --- a/src/compiler/mips/instruction-selector-mips.cc +++ b/src/compiler/mips/instruction-selector-mips.cc @@ -463,10 +463,14 @@ void InstructionSelector::VisitFloat32Min(Node* node) { UNREACHABLE(); } void InstructionSelector::VisitFloat64Min(Node* node) { UNREACHABLE(); } -void InstructionSelector::VisitFloat32Abs(Node* node) { UNREACHABLE(); } +void InstructionSelector::VisitFloat32Abs(Node* node) { + VisitRR(this, kMipsAbsS, node); +} -void InstructionSelector::VisitFloat64Abs(Node* node) { UNREACHABLE(); } +void InstructionSelector::VisitFloat64Abs(Node* node) { + VisitRR(this, kMipsAbsD, node); +} void InstructionSelector::VisitFloat32Sqrt(Node* node) { @@ -970,11 +974,14 @@ void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) { // static MachineOperatorBuilder::Flags InstructionSelector::SupportedMachineOperatorFlags() { + MachineOperatorBuilder::Flags flags = + MachineOperatorBuilder::kFloat32Abs | MachineOperatorBuilder::kFloat64Abs; + if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { - return MachineOperatorBuilder::kFloat64RoundDown | - MachineOperatorBuilder::kFloat64RoundTruncate; + flags |= MachineOperatorBuilder::kFloat64RoundDown | + MachineOperatorBuilder::kFloat64RoundTruncate; } - return MachineOperatorBuilder::kNoFlags; + return flags; } } // namespace compiler diff --git a/src/compiler/mips64/code-generator-mips64.cc b/src/compiler/mips64/code-generator-mips64.cc index 9297a533f..8091ff969 100644 --- a/src/compiler/mips64/code-generator-mips64.cc +++ b/src/compiler/mips64/code-generator-mips64.cc @@ -639,6 +639,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { __ MovFromFloatResult(i.OutputSingleRegister()); break; } + case kMips64AbsS: + __ abs_s(i.OutputSingleRegister(), i.InputSingleRegister(0)); + break; case kMips64SqrtS: { __ sqrt_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); break; @@ -677,6 +680,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { __ MovFromFloatResult(i.OutputDoubleRegister()); break; } + case kMips64AbsD: + __ abs_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); + break; case kMips64SqrtD: { __ sqrt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); break; diff --git a/src/compiler/mips64/instruction-codes-mips64.h b/src/compiler/mips64/instruction-codes-mips64.h index b0e04425e..7c09a4291 100644 --- a/src/compiler/mips64/instruction-codes-mips64.h +++ b/src/compiler/mips64/instruction-codes-mips64.h @@ -51,6 +51,7 @@ namespace compiler { V(Mips64MulS) \ V(Mips64DivS) \ V(Mips64ModS) \ + V(Mips64AbsS) \ V(Mips64SqrtS) \ V(Mips64CmpD) \ V(Mips64AddD) \ @@ -58,6 +59,7 @@ namespace compiler { V(Mips64MulD) \ V(Mips64DivD) \ V(Mips64ModD) \ + V(Mips64AbsD) \ V(Mips64SqrtD) \ V(Mips64Float64RoundDown) \ V(Mips64Float64RoundTruncate) \ diff --git a/src/compiler/mips64/instruction-selector-mips64.cc b/src/compiler/mips64/instruction-selector-mips64.cc index 98497c65f..cfb2742d9 100644 --- a/src/compiler/mips64/instruction-selector-mips64.cc +++ b/src/compiler/mips64/instruction-selector-mips64.cc @@ -612,10 +612,14 @@ void InstructionSelector::VisitFloat32Min(Node* node) { UNREACHABLE(); } void InstructionSelector::VisitFloat64Min(Node* node) { UNREACHABLE(); } -void InstructionSelector::VisitFloat32Abs(Node* node) { UNREACHABLE(); } +void InstructionSelector::VisitFloat32Abs(Node* node) { + VisitRR(this, kMips64AbsS, node); +} -void InstructionSelector::VisitFloat64Abs(Node* node) { UNREACHABLE(); } +void InstructionSelector::VisitFloat64Abs(Node* node) { + VisitRR(this, kMips64AbsD, node); +} void InstructionSelector::VisitFloat32Sqrt(Node* node) { @@ -1182,7 +1186,9 @@ void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) { // static MachineOperatorBuilder::Flags InstructionSelector::SupportedMachineOperatorFlags() { - return MachineOperatorBuilder::kFloat64RoundDown | + return MachineOperatorBuilder::kFloat32Abs | + MachineOperatorBuilder::kFloat64Abs | + MachineOperatorBuilder::kFloat64RoundDown | MachineOperatorBuilder::kFloat64RoundTruncate; } diff --git a/src/mips/assembler-mips.cc b/src/mips/assembler-mips.cc index 769abdb94..c96c05b2b 100644 --- a/src/mips/assembler-mips.cc +++ b/src/mips/assembler-mips.cc @@ -2119,6 +2119,11 @@ void Assembler::div_d(FPURegister fd, FPURegister fs, FPURegister ft) { } +void Assembler::abs_s(FPURegister fd, FPURegister fs) { + GenInstrRegister(COP1, S, f0, fs, fd, ABS_D); +} + + void Assembler::abs_d(FPURegister fd, FPURegister fs) { GenInstrRegister(COP1, D, f0, fs, fd, ABS_D); } diff --git a/src/mips/assembler-mips.h b/src/mips/assembler-mips.h index 73511ac53..1e5748c27 100644 --- a/src/mips/assembler-mips.h +++ b/src/mips/assembler-mips.h @@ -893,6 +893,7 @@ class Assembler : public AssemblerBase { void madd_d(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft); void div_s(FPURegister fd, FPURegister fs, FPURegister ft); void div_d(FPURegister fd, FPURegister fs, FPURegister ft); + void abs_s(FPURegister fd, FPURegister fs); void abs_d(FPURegister fd, FPURegister fs); void mov_d(FPURegister fd, FPURegister fs); void neg_s(FPURegister fd, FPURegister fs); diff --git a/src/mips64/assembler-mips64.cc b/src/mips64/assembler-mips64.cc index 3b4185145..0a8c1fb47 100644 --- a/src/mips64/assembler-mips64.cc +++ b/src/mips64/assembler-mips64.cc @@ -2321,6 +2321,11 @@ void Assembler::div_d(FPURegister fd, FPURegister fs, FPURegister ft) { } +void Assembler::abs_s(FPURegister fd, FPURegister fs) { + GenInstrRegister(COP1, S, f0, fs, fd, ABS_D); +} + + void Assembler::abs_d(FPURegister fd, FPURegister fs) { GenInstrRegister(COP1, D, f0, fs, fd, ABS_D); } diff --git a/src/mips64/assembler-mips64.h b/src/mips64/assembler-mips64.h index 8bc8c836d..70f2eefd4 100644 --- a/src/mips64/assembler-mips64.h +++ b/src/mips64/assembler-mips64.h @@ -923,6 +923,7 @@ class Assembler : public AssemblerBase { void madd_d(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft); void div_s(FPURegister fd, FPURegister fs, FPURegister ft); void div_d(FPURegister fd, FPURegister fs, FPURegister ft); + void abs_s(FPURegister fd, FPURegister fs); void abs_d(FPURegister fd, FPURegister fs); void mov_d(FPURegister fd, FPURegister fs); void neg_s(FPURegister fd, FPURegister fs); diff --git a/test/unittests/compiler/mips/instruction-selector-mips-unittest.cc b/test/unittests/compiler/mips/instruction-selector-mips-unittest.cc index bafa89d58..1dbaa9f60 100644 --- a/test/unittests/compiler/mips/instruction-selector-mips-unittest.cc +++ b/test/unittests/compiler/mips/instruction-selector-mips-unittest.cc @@ -815,6 +815,36 @@ TEST_F(InstructionSelectorTest, Word32Clz) { EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); } + +TEST_F(InstructionSelectorTest, Float32Abs) { + StreamBuilder m(this, kMachFloat32, kMachFloat32); + Node* const p0 = m.Parameter(0); + Node* const n = m.Float32Abs(p0); + m.Return(n); + Stream s = m.Build(); + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kMipsAbsS, s[0]->arch_opcode()); + ASSERT_EQ(1U, s[0]->InputCount()); + EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); + ASSERT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); +} + + +TEST_F(InstructionSelectorTest, Float64Abs) { + StreamBuilder m(this, kMachFloat64, kMachFloat64); + Node* const p0 = m.Parameter(0); + Node* const n = m.Float64Abs(p0); + m.Return(n); + Stream s = m.Build(); + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kMipsAbsD, s[0]->arch_opcode()); + ASSERT_EQ(1U, s[0]->InputCount()); + EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); + ASSERT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); +} + } // namespace compiler } // namespace internal } // namespace v8 diff --git a/test/unittests/compiler/mips64/instruction-selector-mips64-unittest.cc b/test/unittests/compiler/mips64/instruction-selector-mips64-unittest.cc index 0953de8c4..00343d202 100644 --- a/test/unittests/compiler/mips64/instruction-selector-mips64-unittest.cc +++ b/test/unittests/compiler/mips64/instruction-selector-mips64-unittest.cc @@ -816,6 +816,36 @@ TEST_F(InstructionSelectorTest, Word32Clz) { EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); } + +TEST_F(InstructionSelectorTest, Float32Abs) { + StreamBuilder m(this, kMachFloat32, kMachFloat32); + Node* const p0 = m.Parameter(0); + Node* const n = m.Float32Abs(p0); + m.Return(n); + Stream s = m.Build(); + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kMips64AbsS, s[0]->arch_opcode()); + ASSERT_EQ(1U, s[0]->InputCount()); + EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); + ASSERT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); +} + + +TEST_F(InstructionSelectorTest, Float64Abs) { + StreamBuilder m(this, kMachFloat64, kMachFloat64); + Node* const p0 = m.Parameter(0); + Node* const n = m.Float64Abs(p0); + m.Return(n); + Stream s = m.Build(); + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kMips64AbsD, s[0]->arch_opcode()); + ASSERT_EQ(1U, s[0]->InputCount()); + EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); + ASSERT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); +} + } // namespace compiler } // namespace internal } // namespace v8 -- 2.34.1