MIPS: [turbofan] Add new Float32Abs and Float64Abs operators.
authorbalazs.kilvady <balazs.kilvady@imgtec.com>
Wed, 8 Apr 2015 19:30:04 +0000 (12:30 -0700)
committerCommit bot <commit-bot@chromium.org>
Wed, 8 Apr 2015 19:30:11 +0000 (19:30 +0000)
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}

12 files changed:
src/compiler/mips/code-generator-mips.cc
src/compiler/mips/instruction-codes-mips.h
src/compiler/mips/instruction-selector-mips.cc
src/compiler/mips64/code-generator-mips64.cc
src/compiler/mips64/instruction-codes-mips64.h
src/compiler/mips64/instruction-selector-mips64.cc
src/mips/assembler-mips.cc
src/mips/assembler-mips.h
src/mips64/assembler-mips64.cc
src/mips64/assembler-mips64.h
test/unittests/compiler/mips/instruction-selector-mips-unittest.cc
test/unittests/compiler/mips64/instruction-selector-mips64-unittest.cc

index 4247a84c5404fb6b47d2884a1c71a35e171f82ff..ec545156e55704b2d5701b2c56ace6baaa6376ff 100644 (file)
@@ -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;
index d40cf14d481c289d5fbcd7ce4a8b839986aa9267..372b41462f4f19077ea79cd6528337886208ef06 100644 (file)
@@ -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)      \
index 61a5a1cfc3f7847a3b2e8dbd0bc0b0514625e09d..28e030fa1aa87fc92f32af17d1832573ffa37f69 100644 (file)
@@ -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
index 9297a533f3682891b1befe1de8dee8c589e2afd6..8091ff96928c54c19a999556a8d6cd2f9f228ac4 100644 (file)
@@ -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;
index b0e04425e5ec1921c25bf67e6b4d83983ef9199d..7c09a4291d58c7bdc6f01eb6761d4dc04fdc994c 100644 (file)
@@ -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)     \
index 98497c65fd737aaebbdf7b73d4afd25a56d6aa41..cfb2742d95db2278e5aff4e2cbc21d820e50268d 100644 (file)
@@ -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;
 }
 
index 769abdb9465e10b6753531381d91b8d6e9eeb22b..c96c05b2b14cb222f0b12633804a6c9eba76877d 100644 (file)
@@ -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);
 }
index 73511ac5333aca3cddd3f353fee70ad16a8043cc..1e5748c27d5131b42ad6b98298ba331c31fbf132 100644 (file)
@@ -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);
index 3b418514577aa7623e83a908226286c3493de383..0a8c1fb4726b036eb06433dcb06dcaf61e693134 100644 (file)
@@ -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);
 }
index 8bc8c836da2fcaf246849cc7ff75e4b09d4a0714..70f2eefd41bbe174938f7d0607062c3bad4e6975 100644 (file)
@@ -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);
index bafa89d581d120b7286537f07be2f8271d2fb49f..1dbaa9f60a37796c103c843ebd525469b33049fd 100644 (file)
@@ -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
index 0953de8c40cd8cdad2e23a0dd3b2cce9dfc07d1a..00343d2023448b7f0e199072ca1719f01a0396f5 100644 (file)
@@ -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