MIPS: [turbofan] Support for %_DoubleHi, %_DoubleLo and %_ConstructDouble.
authorbalazs.kilvady <balazs.kilvady@imgtec.com>
Thu, 5 Mar 2015 19:28:12 +0000 (11:28 -0800)
committerCommit bot <commit-bot@chromium.org>
Thu, 5 Mar 2015 19:28:28 +0000 (19:28 +0000)
Port 4436c2642a9b7adc9a1b68577ae9ca9a9a404c06

Original commit message:
This adds support for the double bits intrinsics to TurboFan, and is
a first step towards fast Math functions inlined into TurboFan code
or even compiled by themselves with TurboFan.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#27028}

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/macro-assembler-mips.cc
src/mips/macro-assembler-mips.h
src/mips64/macro-assembler-mips64.cc
src/mips64/macro-assembler-mips64.h

index 997f3fe591708c29e7f9a5d342e8ff9a2b65d019..6c299b0f227e515707061a3dc226a9dd19275f0d 100644 (file)
@@ -621,6 +621,18 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       __ Trunc_uw_d(i.InputDoubleRegister(0), i.OutputRegister(), scratch);
       break;
     }
+    case kMipsFmoveLowUwD:
+      __ FmoveLow(i.OutputRegister(), i.InputDoubleRegister(0));
+      break;
+    case kMipsFmoveLowDUw:
+      __ FmoveLow(i.OutputDoubleRegister(), i.InputRegister(1));
+      break;
+    case kMipsFmoveHighUwD:
+      __ FmoveHigh(i.OutputRegister(), i.InputDoubleRegister(0));
+      break;
+    case kMipsFmoveHighDUw:
+      __ FmoveHigh(i.OutputDoubleRegister(), i.InputRegister(1));
+      break;
     // ... more basic instructions ...
 
     case kMipsLbu:
index 3aa508f9d512f7cebadffbadd32092220cffc95a..86817402f43767dee467bccb808be2241b0d87c5 100644 (file)
@@ -61,6 +61,10 @@ namespace compiler {
   V(MipsSwc1)                      \
   V(MipsLdc1)                      \
   V(MipsSdc1)                      \
+  V(MipsFmoveLowUwD)               \
+  V(MipsFmoveLowDUw)               \
+  V(MipsFmoveHighUwD)              \
+  V(MipsFmoveHighDUw)              \
   V(MipsPush)                      \
   V(MipsStoreToStackSlot)          \
   V(MipsStackClaim)                \
index ffe8263d88569c1e5439fbb9e8a2a4b972cffe2d..32214b1be7c32037403f09a46ffb411639e6f4c0 100644 (file)
@@ -885,6 +885,38 @@ void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
 }
 
 
+void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) {
+  MipsOperandGenerator g(this);
+  Emit(kMipsFmoveLowUwD, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) {
+  MipsOperandGenerator g(this);
+  Emit(kMipsFmoveHighUwD, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) {
+  MipsOperandGenerator g(this);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  Emit(kMipsFmoveLowDUw, g.DefineSameAsFirst(node), g.UseRegister(left),
+       g.UseRegister(right));
+}
+
+
+void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) {
+  MipsOperandGenerator g(this);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  Emit(kMipsFmoveHighDUw, g.DefineSameAsFirst(node), g.UseRegister(left),
+       g.UseRegister(right));
+}
+
+
 // static
 MachineOperatorBuilder::Flags
 InstructionSelector::SupportedMachineOperatorFlags() {
index 190001228c091c620fd501dc63800ff9745efeb3..1746afe2fa9996227679b73ce0a33e0fcc02d80f 100644 (file)
@@ -685,6 +685,21 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       __ Trunc_uw_d(i.InputDoubleRegister(0), i.OutputRegister(), scratch);
       break;
     }
+    case kMips64FmoveLowUwD:
+      __ FmoveLow(i.OutputRegister(), i.InputDoubleRegister(0));
+      // remove sign.
+      __ dsll32(i.OutputRegister(), i.OutputRegister(), 0);
+      __ dsrl32(i.OutputRegister(), i.OutputRegister(), 0);
+      break;
+    case kMips64FmoveLowDUw:
+      __ FmoveLow(i.OutputDoubleRegister(), i.InputRegister(1));
+      break;
+    case kMips64FmoveHighUwD:
+      __ FmoveHigh(i.OutputRegister(), i.InputDoubleRegister(0));
+      break;
+    case kMips64FmoveHighDUw:
+      __ FmoveHigh(i.OutputDoubleRegister(), i.InputRegister(1));
+      break;
     // ... more basic instructions ...
 
     case kMips64Lbu:
index dd019f9e5accb7ec2bc5daf5b5b15bcd7f746665..bae6e24081195d29e2ab8d5b0f8da481038cf5bc 100644 (file)
@@ -76,6 +76,10 @@ namespace compiler {
   V(Mips64Swc1)                    \
   V(Mips64Ldc1)                    \
   V(Mips64Sdc1)                    \
+  V(Mips64FmoveLowUwD)             \
+  V(Mips64FmoveLowDUw)             \
+  V(Mips64FmoveHighUwD)            \
+  V(Mips64FmoveHighDUw)            \
   V(Mips64Push)                    \
   V(Mips64StoreToStackSlot)        \
   V(Mips64StackClaim)              \
index aba81d5d9d335f7967948814d136289684d7392c..6a8d7420e0c982d9ba90f6f3d76e425479d5a1a8 100644 (file)
@@ -1137,6 +1137,38 @@ void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
 }
 
 
+void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) {
+  Mips64OperandGenerator g(this);
+  Emit(kMips64FmoveLowUwD, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) {
+  Mips64OperandGenerator g(this);
+  Emit(kMips64FmoveHighUwD, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) {
+  Mips64OperandGenerator g(this);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  Emit(kMips64FmoveLowDUw, g.DefineSameAsFirst(node), g.UseRegister(left),
+       g.UseRegister(right));
+}
+
+
+void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) {
+  Mips64OperandGenerator g(this);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  Emit(kMips64FmoveHighDUw, g.DefineSameAsFirst(node), g.UseRegister(left),
+       g.UseRegister(right));
+}
+
+
 // static
 MachineOperatorBuilder::Flags
 InstructionSelector::SupportedMachineOperatorFlags() {
index ae44b3d4db197cee34996f7e29fba11afb8322e1..f965e8ba48ff16ede91dc12e38258f800c7d3d11 100644 (file)
@@ -1549,6 +1549,18 @@ void MacroAssembler::BranchF(Label* target,
 }
 
 
+void MacroAssembler::FmoveLow(FPURegister dst, Register src_low) {
+  if (IsFp64Mode()) {
+    DCHECK(!src_low.is(at));
+    mfhc1(at, dst);
+    mtc1(src_low, dst);
+    mthc1(at, dst);
+  } else {
+    mtc1(src_low, dst);
+  }
+}
+
+
 void MacroAssembler::Move(FPURegister dst, float imm) {
   li(at, Operand(bit_cast<int32_t>(imm)));
   mtc1(at, dst);
index f29c2ee93d8048b80baab44a5cd7df7c588a885f..44f6c4b58adad2ba60b07efa90f2b48af2757336 100644 (file)
@@ -241,10 +241,16 @@ class MacroAssembler: public Assembler {
     Mfhc1(dst_high, src);
   }
 
+  inline void FmoveHigh(FPURegister dst, Register src_high) {
+    Mthc1(src_high, dst);
+  }
+
   inline void FmoveLow(Register dst_low, FPURegister src) {
     mfc1(dst_low, src);
   }
 
+  void FmoveLow(FPURegister dst, Register src_low);
+
   inline void Move(FPURegister dst, Register src_low, Register src_high) {
     mtc1(src_low, dst);
     Mthc1(src_high, dst);
index d187fa5423702ddb8dc42648043a090d2605c48d..fbd5520be8a6998cdeaecdb300a237c4d30d4b6a 100644 (file)
@@ -1717,6 +1717,14 @@ void MacroAssembler::BranchF(Label* target,
 }
 
 
+void MacroAssembler::FmoveLow(FPURegister dst, Register src_low) {
+  DCHECK(!src_low.is(at));
+  mfhc1(at, dst);
+  mtc1(src_low, dst);
+  mthc1(at, dst);
+}
+
+
 void MacroAssembler::Move(FPURegister dst, float imm) {
   li(at, Operand(bit_cast<int32_t>(imm)));
   mtc1(at, dst);
index 3d428f77766a4676bf530936d5be85f88286dc27..3c1c2b0a50346e5071af8723cbdd54285385ce65 100644 (file)
@@ -262,10 +262,16 @@ class MacroAssembler: public Assembler {
     mfhc1(dst_high, src);
   }
 
+  inline void FmoveHigh(FPURegister dst, Register src_high) {
+    mthc1(src_high, dst);
+  }
+
   inline void FmoveLow(Register dst_low, FPURegister src) {
     mfc1(dst_low, src);
   }
 
+  void FmoveLow(FPURegister dst, Register src_low);
+
   inline void Move(FPURegister dst, Register src_low, Register src_high) {
     mtc1(src_low, dst);
     mthc1(src_high, dst);