Reviewers: titzer, danno, Benedikt Meurer,

Message:
PTAL

Description:
[turbofan] IA: Float64ToUint32 supports mem operand

BUG=

Please review this at https://codereview.chromium.org/582713002/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+86, -12 lines):
  M src/compiler/ia32/code-generator-ia32.cc
  M src/compiler/ia32/instruction-selector-ia32.cc
  M src/compiler/x64/code-generator-x64.cc
  M src/compiler/x64/instruction-selector-x64.cc
  M src/ia32/assembler-ia32.h
  M src/ia32/assembler-ia32.cc
  M src/x64/assembler-x64.h
  M src/x64/assembler-x64.cc
  M test/cctest/compiler/test-run-machops.cc
  M test/cctest/test-disasm-ia32.cc
  M test/cctest/test-disasm-x64.cc


Index: src/compiler/ia32/code-generator-ia32.cc
diff --git a/src/compiler/ia32/code-generator-ia32.cc b/src/compiler/ia32/code-generator-ia32.cc index 3a3fd795d8d38cd164fc68e7f6129265548d05f5..a0d30e6ba8038b79527f1da11748388c65896682 100644
--- a/src/compiler/ia32/code-generator-ia32.cc
+++ b/src/compiler/ia32/code-generator-ia32.cc
@@ -302,11 +302,17 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       break;
     case kSSEFloat64ToUint32: {
       XMMRegister scratch = xmm0;
+      Label done;
       __ Move(scratch, -2147483648.0);
-      // TODO(turbofan): IA32 SSE subsd() should take an operand.
-      __ addsd(scratch, i.InputDoubleRegister(0));
+      __ addsd(scratch, i.InputOperand(0));
       __ cvttsd2si(i.OutputRegister(), scratch);
       __ add(i.OutputRegister(), Immediate(0x80000000));
+      __ j(not_carry, &done, Label::kNear);
+      __ cvtsi2sd(scratch, i.OutputRegister());
+      __ ucomisd(scratch, i.InputOperand(0));
+      __ j(equal, &done, Label::kNear);
+      __ sub(i.OutputRegister(), Immediate(1));
+      __ bind(&done);
       break;
     }
     case kSSEInt32ToFloat64:
Index: src/compiler/ia32/instruction-selector-ia32.cc
diff --git a/src/compiler/ia32/instruction-selector-ia32.cc b/src/compiler/ia32/instruction-selector-ia32.cc index eb3752cde17046d30ceed70e224c2b9389940ed8..42702c172305b9e8e494b2bd00b87bfa5cd66244 100644
--- a/src/compiler/ia32/instruction-selector-ia32.cc
+++ b/src/compiler/ia32/instruction-selector-ia32.cc
@@ -376,9 +376,7 @@ void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {

 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) {
   IA32OperandGenerator g(this);
-  // TODO(turbofan): IA32 SSE subsd() should take an operand.
-  Emit(kSSEFloat64ToUint32, g.DefineAsRegister(node),
-       g.UseRegister(node->InputAt(0)));
+ Emit(kSSEFloat64ToUint32, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
 }


Index: src/compiler/x64/code-generator-x64.cc
diff --git a/src/compiler/x64/code-generator-x64.cc b/src/compiler/x64/code-generator-x64.cc index f93ad21a219a09c0ca51f556dbf9d457a8a58ad1..1c2d3ee88535559fe4c737d5c39ff6d0b139e18d 100644
--- a/src/compiler/x64/code-generator-x64.cc
+++ b/src/compiler/x64/code-generator-x64.cc
@@ -469,11 +469,13 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       break;
     }
     case kSSEFloat64ToUint32: {
-      // TODO(turbofan): X64 SSE cvttsd2siq should support operands.
-      __ cvttsd2siq(i.OutputRegister(), i.InputDoubleRegister(0));
+      RegisterOrOperand input = i.InputRegisterOrOperand(0);
+      if (input.type == kDoubleRegister) {
+        __ cvttsd2siq(i.OutputRegister(), input.double_reg);
+      } else {
+        __ cvttsd2siq(i.OutputRegister(), input.operand);
+      }
__ andl(i.OutputRegister(), i.OutputRegister()); // clear upper bits. - // TODO(turbofan): generated code should not look at the upper 32 bits
-      // of the result, but those bits could escape to the outside world.
       break;
     }
     case kSSEInt32ToFloat64: {
Index: src/compiler/x64/instruction-selector-x64.cc
diff --git a/src/compiler/x64/instruction-selector-x64.cc b/src/compiler/x64/instruction-selector-x64.cc index 8d41fa1871c906bc21b89ddb2b6762bae9d19f6e..e041a7484295b80b8c9077446f6c3006b076cf69 100644
--- a/src/compiler/x64/instruction-selector-x64.cc
+++ b/src/compiler/x64/instruction-selector-x64.cc
@@ -500,9 +500,7 @@ void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {

 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) {
   X64OperandGenerator g(this);
-  // TODO(turbofan): X64 SSE cvttsd2siq should support operands.
-  Emit(kSSEFloat64ToUint32, g.DefineAsRegister(node),
-       g.UseRegister(node->InputAt(0)));
+ Emit(kSSEFloat64ToUint32, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
 }


Index: src/ia32/assembler-ia32.cc
diff --git a/src/ia32/assembler-ia32.cc b/src/ia32/assembler-ia32.cc
index 5dc733ad9b90f20df178217c5d8e6812a9b507d3..d16eea16302347d3891469eb38da820bdcabae57 100644
--- a/src/ia32/assembler-ia32.cc
+++ b/src/ia32/assembler-ia32.cc
@@ -2014,6 +2014,15 @@ void Assembler::subsd(XMMRegister dst, XMMRegister src) {
 }


+void Assembler::subsd(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  EMIT(0xF2);
+  EMIT(0x0F);
+  EMIT(0x5C);
+  emit_sse_operand(dst, src);
+}
+
+
 void Assembler::divsd(XMMRegister dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
   EMIT(0xF2);
Index: src/ia32/assembler-ia32.h
diff --git a/src/ia32/assembler-ia32.h b/src/ia32/assembler-ia32.h
index 5febffd8c389dffcdced09d437e0c9a17399dc0f..81757788f0931421eed718e0dd4ab256bb9d3d52 100644
--- a/src/ia32/assembler-ia32.h
+++ b/src/ia32/assembler-ia32.h
@@ -956,6 +956,7 @@ class Assembler : public AssemblerBase {
   void addsd(XMMRegister dst, XMMRegister src);
   void addsd(XMMRegister dst, const Operand& src);
   void subsd(XMMRegister dst, XMMRegister src);
+  void subsd(XMMRegister dst, const Operand& src);
   void mulsd(XMMRegister dst, XMMRegister src);
   void mulsd(XMMRegister dst, const Operand& src);
   void divsd(XMMRegister dst, XMMRegister src);
Index: src/x64/assembler-x64.cc
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc
index 1dba9b031e59fad60c7542996d71b737cd3ccdbd..4f8d5b1be13e443e77e2fbba613b550eaa314acb 100644
--- a/src/x64/assembler-x64.cc
+++ b/src/x64/assembler-x64.cc
@@ -2629,6 +2629,16 @@ void Assembler::cvttsd2siq(Register dst, XMMRegister src) {
 }


+void Assembler::cvttsd2siq(Register dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit(0xF2);
+  emit_rex_64(dst, src);
+  emit(0x0F);
+  emit(0x2C);
+  emit_sse_operand(dst, src);
+}
+
+
 void Assembler::cvtlsi2sd(XMMRegister dst, const Operand& src) {
   EnsureSpace ensure_space(this);
   emit(0xF2);
@@ -2900,6 +2910,12 @@ void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
 }


+void Assembler::emit_sse_operand(Register reg, const Operand& adr) {
+  Register ireg = {reg.code()};
+  emit_operand(ireg, adr);
+}
+
+
 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
   emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
 }
Index: src/x64/assembler-x64.h
diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h
index 3896f8923daa6ede6316567d253ddd7f11ee0930..b2a97cc64208572b297a65ea73a07f52dc61f0f9 100644
--- a/src/x64/assembler-x64.h
+++ b/src/x64/assembler-x64.h
@@ -1048,6 +1048,7 @@ class Assembler : public AssemblerBase {
   void cvttsd2si(Register dst, const Operand& src);
   void cvttsd2si(Register dst, XMMRegister src);
   void cvttsd2siq(Register dst, XMMRegister src);
+  void cvttsd2siq(Register dst, const Operand& src);

   void cvtlsi2sd(XMMRegister dst, const Operand& src);
   void cvtlsi2sd(XMMRegister dst, Register src);
@@ -1316,6 +1317,7 @@ class Assembler : public AssemblerBase {
// The first argument is the reg field, the second argument is the r/m field.
   void emit_sse_operand(XMMRegister dst, XMMRegister src);
   void emit_sse_operand(XMMRegister reg, const Operand& adr);
+  void emit_sse_operand(Register reg, const Operand& adr);
   void emit_sse_operand(XMMRegister dst, Register src);
   void emit_sse_operand(Register dst, XMMRegister src);

Index: test/cctest/compiler/test-run-machops.cc
diff --git a/test/cctest/compiler/test-run-machops.cc b/test/cctest/compiler/test-run-machops.cc index bbe75db4bcab10508a7536c1a90bfdbcae3fb957..798532520e6498fec86970a56a3a1e3a4fdeb175 100644
--- a/test/cctest/compiler/test-run-machops.cc
+++ b/test/cctest/compiler/test-run-machops.cc
@@ -3232,6 +3232,46 @@ TEST(RunChangeFloat64ToInt32_spilled) {
 }


+TEST(RunChangeFloat64ToUint32_spilled) {
+  RawMachineAssemblerTester<uint32_t> m;
+  const int kNumInputs = 32;
+  int32_t magic = 0x786234;
+  double input[kNumInputs];
+  uint32_t 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(kMachUint32, m.PointerConstant(&result), m.Int32Constant(i * 4),
+            m.ChangeFloat64ToUint32(input_node[i]));
+  }
+
+  m.Return(m.Int32Constant(magic));
+
+  for (int i = 0; i < kNumInputs; i++) {
+    if (i % 2) {
+      input[i] = 100.9 + i + 2147483648;
+    } else {
+      input[i] = 100.9 + i;
+    }
+  }
+
+  CHECK_EQ(magic, m.Call());
+
+  for (int i = 0; i < kNumInputs; i++) {
+    if (i % 2) {
+      CHECK_EQ(result[i], 100 + i + 2147483648);
+    } else {
+      CHECK_EQ(result[i], 100 + i);
+    }
+  }
+}
+
+
 TEST(RunDeadChangeFloat64ToInt32) {
   RawMachineAssemblerTester<int32_t> m;
   const int magic = 0x88abcda4;
Index: test/cctest/test-disasm-ia32.cc
diff --git a/test/cctest/test-disasm-ia32.cc b/test/cctest/test-disasm-ia32.cc index 76452ef91e2d7fe0bf18fd34e1cbbde825a5bb9e..49088f6e94da8223ad3afc124ac85d637e958350 100644
--- a/test/cctest/test-disasm-ia32.cc
+++ b/test/cctest/test-disasm-ia32.cc
@@ -416,6 +416,7 @@ TEST(DisasmIa320) {
     __ addsd(xmm1, xmm0);
     __ mulsd(xmm1, xmm0);
     __ subsd(xmm1, xmm0);
+    __ subsd(xmm1, Operand(ebx, ecx, times_4, 10000));
     __ divsd(xmm1, xmm0);
     __ ucomisd(xmm0, xmm1);
     __ cmpltsd(xmm0, xmm1);
Index: test/cctest/test-disasm-x64.cc
diff --git a/test/cctest/test-disasm-x64.cc b/test/cctest/test-disasm-x64.cc
index a842956ae82336fafa962bca1b8fe9e1935c1d1a..e756ce220b6817cbb65e61554c8f325e9d6961d3 100644
--- a/test/cctest/test-disasm-x64.cc
+++ b/test/cctest/test-disasm-x64.cc
@@ -378,6 +378,7 @@ TEST(DisasmX64) {
     __ cvttsd2si(rdx, Operand(rbx, rcx, times_4, 10000));
     __ cvttsd2si(rdx, xmm1);
     __ cvttsd2siq(rdx, xmm1);
+    __ cvttsd2siq(rdx, Operand(rbx, rcx, times_4, 10000));
     __ movsd(xmm1, Operand(rbx, rcx, times_4, 10000));
     __ movsd(Operand(rbx, rcx, times_4, 10000), xmm1);
     // 128 bit move instructions.


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to