Reviewers: titzer,

Message:
PTAL.

Description:
Add Float64Round operator.

[email protected]

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

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

Affected files (+82, -3 lines):
  M src/compiler/machine-operator.h
  M src/compiler/machine-operator.cc
  M src/compiler/opcodes.h
  M src/compiler/simplified-lowering.cc
  M src/compiler/typer.cc
  M src/compiler/verifier.cc


Index: src/compiler/machine-operator.cc
diff --git a/src/compiler/machine-operator.cc b/src/compiler/machine-operator.cc index b5da8297e1d2c62e73d06866f50d8eaa489ea071..b151734d59e3da8771cd97cf5c46794b6ea22976 100644
--- a/src/compiler/machine-operator.cc
+++ b/src/compiler/machine-operator.cc
@@ -181,6 +181,20 @@ struct MachineOperatorBuilderImpl {
   Store##Type##FullWriteBarrier##Operator k##Store##Type##FullWriteBarrier;
   MACHINE_TYPE_LIST(STORE)
 #undef STORE
+
+  struct Float64RoundOperator FINAL : public Operator1<Float64RoundMode> {
+    explicit Float64RoundOperator(Float64RoundMode mode)
+        : Operator1(IrOpcode::kFloat64Round, Operator::kPure, 1, 1,
+                    "Float64Round", mode) {}
+  };
+  Float64RoundOperator kFloat64RoundJavascript;
+  Float64RoundOperator kFloat64RoundDown;
+  Float64RoundOperator kFloat64RoundUp;
+
+  MachineOperatorBuilderImpl()
+      : kFloat64RoundJavascript(kRoundJavascript),
+        kFloat64RoundDown(kRoundDown),
+        kFloat64RoundUp(kRoundUp) {}
 };


@@ -188,8 +202,14 @@ static base::LazyInstance<MachineOperatorBuilderImpl>::type kImpl =
     LAZY_INSTANCE_INITIALIZER;


-MachineOperatorBuilder::MachineOperatorBuilder(MachineType word)
-    : impl_(kImpl.Get()), word_(word) {
+MachineOperatorBuilder::MachineOperatorBuilder(MachineType word,
+                                               bool hasFloat64Round)
+    : impl_(kImpl.Get()),
+      word_(word)
+#define ARG(Name) , has##Name##_(has##Name)
+      BACKEND_SPECIFIC_OPS(ARG)
+#undef ARG
+{
   DCHECK(word == kRepWord32 || word == kRepWord64);
 }

@@ -237,6 +257,26 @@ const Operator* MachineOperatorBuilder::Store(StoreRepresentation rep) {
   return NULL;
 }

+
+const Operator* MachineOperatorBuilder::Float64Round(Float64RoundMode mode) {
+  switch (mode) {
+    case kRoundJavascript:
+      return &impl_.kFloat64RoundJavascript;
+    case kRoundDown:
+      return &impl_.kFloat64RoundDown;
+    case kRoundUp:
+      return &impl_.kFloat64RoundUp;
+  }
+  UNREACHABLE();
+  return NULL;
+}
+
+
+// Backend specific configuration.
+
+// static
+bool MachineOperatorBuilder::ProvidesFloat64Round() { return false; }
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
Index: src/compiler/machine-operator.h
diff --git a/src/compiler/machine-operator.h b/src/compiler/machine-operator.h index 568d3eb2b89acc163584aea605375772ccfed1f0..07af515122f84614a6186315fb0da75206035953 100644
--- a/src/compiler/machine-operator.h
+++ b/src/compiler/machine-operator.h
@@ -51,13 +51,24 @@ std::ostream& operator<<(std::ostream&, StoreRepresentation);

 StoreRepresentation const& StoreRepresentationOf(Operator const*);

+// Rounding mode for double rounding.
+enum Float64RoundMode {
+ kRoundJavascript, // Rounding, tie: whichever is closer to positive infinity.
+  kRoundDown,
+  kRoundUp
+};
+
+// These operations may not be provided by all backends.
+#define BACKEND_SPECIFIC_OPS(V) V(Float64Round)

 // Interface for building machine-level operators. These operators are
// machine-level but machine-independent and thus define a language suitable
 // for generating code to run on architectures such as ia32, x64, arm, etc.
 class MachineOperatorBuilder FINAL {
  public:
-  explicit MachineOperatorBuilder(MachineType word = kMachPtr);
+  explicit MachineOperatorBuilder(
+      MachineType word = kMachPtr,
+      bool hasFloat64Round = ProvidesFloat64Round());

   const Operator* Word32And();
   const Operator* Word32Or();
@@ -122,6 +133,9 @@ class MachineOperatorBuilder FINAL {
   const Operator* TruncateFloat64ToInt32();  // JavaScript semantics.
   const Operator* TruncateInt64ToInt32();

+  // Rounds a number depending on rounding mode.
+  const Operator* Float64Round(Float64RoundMode mode);
+
// Floating point operators always operate with IEEE 754 round-to-nearest.
   const Operator* Float64Add();
   const Operator* Float64Sub();
@@ -149,6 +163,12 @@ class MachineOperatorBuilder FINAL {
   bool Is64() const { return word() == kRepWord64; }
   MachineType word() const { return word_; }

+// Getters to test if backend specific operation is available.
+#define GETTER(Name) \
+  bool Has##Name() { return has##Name##_; }
+  BACKEND_SPECIFIC_OPS(GETTER)
+#undef GETTER
+
 // Pseudo operators that translate to 32/64-bit operators depending on the
 // word-size of the target machine assumed by this builder.
 #define PSEUDO_OP_LIST(V) \
@@ -181,6 +201,16 @@ class MachineOperatorBuilder FINAL {
  private:
   const MachineOperatorBuilderImpl& impl_;
   const MachineType word_;
+// Flags for backend-specific operations.
+#define FIELD(Name) bool has##Name##_;
+  BACKEND_SPECIFIC_OPS(FIELD)
+#undef FIELD
+
+// Backend-specific operator configuration. These are implemented by
+// each back-end.
+#define DECL(Name) static bool Provides##Name();
+  BACKEND_SPECIFIC_OPS(DECL)
+#undef DECL
 };

 }  // namespace compiler
Index: src/compiler/opcodes.h
diff --git a/src/compiler/opcodes.h b/src/compiler/opcodes.h
index 8b68e603fb882ec6f2f8a89a3f783470e057e414..875e348bb23c2e363558b6f8a5dbcb8fcaef430f 100644
--- a/src/compiler/opcodes.h
+++ b/src/compiler/opcodes.h
@@ -225,6 +225,7 @@
   V(Float64Equal)             \
   V(Float64LessThan)          \
   V(Float64LessThanOrEqual)   \
+  V(Float64Round)             \
   V(LoadStackPointer)

 #define VALUE_OP_LIST(V) \
Index: src/compiler/simplified-lowering.cc
diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc index ae65d169695f007b3e4244dc7c828f6bdbed594e..7d72dd9c14d41f0fac6e409470fc6d261c92911a 100644
--- a/src/compiler/simplified-lowering.cc
+++ b/src/compiler/simplified-lowering.cc
@@ -853,6 +853,7 @@ class RepresentationSelector {
       case IrOpcode::kFloat64Mod:
         return VisitFloat64Binop(node);
       case IrOpcode::kFloat64Sqrt:
+      case IrOpcode::kFloat64Round:
         return VisitUnop(node, kMachFloat64, kMachFloat64);
       case IrOpcode::kFloat64Equal:
       case IrOpcode::kFloat64LessThan:
Index: src/compiler/typer.cc
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc
index 70f80cbb6b81868b9dec5b90e7e2442084753e20..c5d3f41a49783ca167270185f85cb20634fec752 100644
--- a/src/compiler/typer.cc
+++ b/src/compiler/typer.cc
@@ -1554,6 +1554,12 @@ Bounds Typer::Visitor::TypeFloat64LessThanOrEqual(Node* node) {
 }


+Bounds Typer::Visitor::TypeFloat64Round(Node* node) {
+  // TODO(sigurds): We could have a tighter bound here.
+  return Bounds(Type::Number());
+}
+
+
 Bounds Typer::Visitor::TypeLoadStackPointer(Node* node) {
   return Bounds(Type::Internal());
 }
Index: src/compiler/verifier.cc
diff --git a/src/compiler/verifier.cc b/src/compiler/verifier.cc
index f2ad4bae70c330b8960c96ff2b01d496c23fb9d6..ec931938a8c462406fbdd4c75ca7a651f3859c07 100644
--- a/src/compiler/verifier.cc
+++ b/src/compiler/verifier.cc
@@ -648,6 +648,7 @@ GenericGraphVisit::Control Verifier::Visitor::Pre(Node* node) {
       case IrOpcode::kFloat64Equal:
       case IrOpcode::kFloat64LessThan:
       case IrOpcode::kFloat64LessThanOrEqual:
+      case IrOpcode::kFloat64Round:
       case IrOpcode::kTruncateInt64ToInt32:
       case IrOpcode::kTruncateFloat64ToFloat32:
       case IrOpcode::kTruncateFloat64ToInt32:


--
--
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