This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[jit] Add operator overloading to the C++ API.


Committed to branch dmalcolm/jit:

gcc/jit/
	* libgccjit++.h (gccjit::object::get_context): New method.
	(gccjit::function): Add overloaded operator () for various
	numbers of arguments as a very terse way of creating function calls.
	(gccjit::rvalue::get_type): New method.

	(operator-): New overloaded unary op for rvalues.
	(operator~): Likewise.
	(operator!): Likewise.

	(operator+): New overloaded binary op for rvalues.
	(operator-): Likewise.
	(operator*): Likewise.
	(operator/): Likewise.
	(operator%): Likewise.
	(operator&): Likewise.
	(operator^): Likewise.
	(operator|): Likewise.
	(operator&&): Likewise.
	(operator||): Likewise.

	(operator==): New overloaded comparison for rvalues.
	(operator!=): Likewise.
	(operator<): Likewise.
	(operator<=): Likewise.
	(operator>): Likewise.
	(operator>=): Likewise.

	(operator*): New overloaded operator for dereferencing an
	rvalue representing a pointer.

	* libgccjit.c (gcc_jit_rvalue_get_type): New.
	* libgccjit.h (gcc_jit_rvalue_get_type): New.
	* libgccjit.map (gcc_jit_rvalue_get_type): New.

gcc/testsuite/
	* jit.dg/test-operator-overloading.cc: New testcase, a
	rewrite of test-quadratic.cc to use operator overloading.
---
 gcc/jit/ChangeLog.jit                             |  36 +++
 gcc/jit/libgccjit++.h                             | 173 ++++++++++++
 gcc/jit/libgccjit.c                               |   8 +
 gcc/jit/libgccjit.h                               |   3 +
 gcc/jit/libgccjit.map                             |   1 +
 gcc/testsuite/ChangeLog.jit                       |   5 +
 gcc/testsuite/jit.dg/test-operator-overloading.cc | 306 ++++++++++++++++++++++
 7 files changed, 532 insertions(+)
 create mode 100644 gcc/testsuite/jit.dg/test-operator-overloading.cc

diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit
index bd209ed..9b44728 100644
--- a/gcc/jit/ChangeLog.jit
+++ b/gcc/jit/ChangeLog.jit
@@ -1,5 +1,41 @@
 2014-02-10  David Malcolm  <dmalcolm@redhat.com>
 
+	* libgccjit++.h (gccjit::object::get_context): New method.
+	(gccjit::function): Add overloaded operator () for various
+	numbers of arguments as a very terse way of creating function calls.
+	(gccjit::rvalue::get_type): New method.
+
+	(operator-): New overloaded unary op for rvalues.
+	(operator~): Likewise.
+	(operator!): Likewise.
+
+	(operator+): New overloaded binary op for rvalues.
+	(operator-): Likewise.
+	(operator*): Likewise.
+	(operator/): Likewise.
+	(operator%): Likewise.
+	(operator&): Likewise.
+	(operator^): Likewise.
+	(operator|): Likewise.
+	(operator&&): Likewise.
+	(operator||): Likewise.
+
+	(operator==): New overloaded comparison for rvalues.
+	(operator!=): Likewise.
+	(operator<): Likewise.
+	(operator<=): Likewise.
+	(operator>): Likewise.
+	(operator>=): Likewise.
+
+	(operator*): New overloaded operator for dereferencing an
+	rvalue representing a pointer.
+
+	* libgccjit.c (gcc_jit_rvalue_get_type): New.
+	* libgccjit.h (gcc_jit_rvalue_get_type): New.
+	* libgccjit.map (gcc_jit_rvalue_get_type): New.
+
+2014-02-10  David Malcolm  <dmalcolm@redhat.com>
+
 	* libgccjit++.h (gccjit::context::new_minus): New method,
 	providing a way to do a specific unary op with less typing.
 	(gccjit::context::new_bitwise_negate): Likewise.
diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h
index ff22d1e..fab1a74 100644
--- a/gcc/jit/libgccjit++.h
+++ b/gcc/jit/libgccjit++.h
@@ -27,6 +27,8 @@ namespace gccjit
   class object
   {
   public:
+    context get_context () const;
+
     std::string get_debug_string () const;
 
   protected:
@@ -296,6 +298,16 @@ namespace gccjit
 
     void add_return (rvalue rvalue,
 		     location loc = location ());
+
+    /* A series of overloaded operator () with various numbers of arguments
+       for a very terse way of creating a call to this function.  The call
+       is created within the same context as the function itself, which may
+       not be what you want.  */
+    rvalue operator() (location loc = location ());
+    rvalue operator() (rvalue arg0,
+		       location loc = location ());
+    rvalue operator() (rvalue arg0, rvalue arg1,
+		       location loc = location ());
   };
 
   class label : public object
@@ -314,6 +326,8 @@ namespace gccjit
     rvalue (gcc_jit_rvalue *inner);
     gcc_jit_rvalue *get_inner_rvalue ();
 
+    type get_type ();
+
     rvalue access_field (field field,
 			 location loc = location ());
 
@@ -345,6 +359,42 @@ namespace gccjit
 
     gcc_jit_param *get_inner_param ();
   };
+
+
+  /* Overloaded operators, for those who want the most terse API
+     (at the possible risk of being a little too magical).
+
+     In each case, the first parameter is used to determine which context
+     owns the resulting expression, and, where appropriate,  what the
+     latter's type is. */
+
+  /* Unary operators.  */
+  rvalue operator- (rvalue a); // unary minus
+  rvalue operator~ (rvalue a); // unary bitwise negate
+  rvalue operator! (rvalue a); // unary logical negate
+
+  /* Binary operators.  */
+  rvalue operator+ (rvalue a, rvalue b);
+  rvalue operator- (rvalue a, rvalue b);
+  rvalue operator* (rvalue a, rvalue b);
+  rvalue operator/ (rvalue a, rvalue b);
+  rvalue operator% (rvalue a, rvalue b);
+  rvalue operator& (rvalue a, rvalue b); //  bitwise and
+  rvalue operator^ (rvalue a, rvalue b); // bitwise_xor
+  rvalue operator| (rvalue a, rvalue b); // bitwise_or
+  rvalue operator&& (rvalue a, rvalue b); // logical_and
+  rvalue operator|| (rvalue a, rvalue b); // logical_or
+
+  /* Comparisons.  */
+  rvalue operator== (rvalue a, rvalue b);
+  rvalue operator!= (rvalue a, rvalue b);
+  rvalue operator< (rvalue a, rvalue b);
+  rvalue operator<= (rvalue a, rvalue b);
+  rvalue operator> (rvalue a, rvalue b);
+  rvalue operator>= (rvalue a, rvalue b);
+
+  /* Dereferencing. */
+  lvalue operator* (rvalue ptr);
 }
 
 /****************************************************************************
@@ -835,6 +885,12 @@ context::new_array_access (rvalue ptr,
 }
 
 // class object
+inline context
+object::get_context () const
+{
+  return context (gcc_jit_object_get_context (m_inner_obj));
+}
+
 inline std::string
 object::get_debug_string () const
 {
@@ -1038,6 +1094,28 @@ function::add_return (rvalue rvalue,
 			       rvalue.get_inner_rvalue ());
 }
 
+inline rvalue
+function::operator() (location loc)
+{
+  return get_context ().new_call (*this, loc);
+}
+inline rvalue
+function::operator() (rvalue arg0,
+		      location loc)
+{
+  return get_context ().new_call (*this,
+				  arg0,
+				  loc);
+}
+inline rvalue
+function::operator() (rvalue arg0, rvalue arg1,
+		      location loc)
+{
+  return get_context ().new_call (*this,
+				  arg0, arg1,
+				  loc);
+}
+
 // class label
 inline label::label () : object (NULL) {}
 inline label::label (gcc_jit_label *inner)
@@ -1064,6 +1142,12 @@ rvalue::get_inner_rvalue ()
   return reinterpret_cast<gcc_jit_rvalue *> (get_inner_object ());
 }
 
+inline type
+rvalue::get_type ()
+{
+  return type (gcc_jit_rvalue_get_type (get_inner_rvalue ()));
+}
+
 inline rvalue
 rvalue::access_field (field field,
 		      location loc)
@@ -1123,6 +1207,95 @@ inline param::param (gcc_jit_param *inner)
   : lvalue (gcc_jit_param_as_lvalue (inner))
 {}
 
+/* Overloaded operators.  */
+// Unary operators
+inline rvalue operator- (rvalue a)
+{
+  return a.get_context ().new_minus (a.get_type (), a);
+}
+inline rvalue operator~ (rvalue a)
+{
+  return a.get_context ().new_bitwise_negate (a.get_type (), a);
+}
+inline rvalue operator! (rvalue a)
+{
+  return a.get_context ().new_logical_negate (a.get_type (), a);
+}
+
+// Binary operators
+inline rvalue operator+ (rvalue a, rvalue b)
+{
+  return a.get_context ().new_plus (a.get_type (), a, b);
+}
+inline rvalue operator- (rvalue a, rvalue b)
+{
+  return a.get_context ().new_minus (a.get_type (), a, b);
+}
+inline rvalue operator* (rvalue a, rvalue b)
+{
+  return a.get_context ().new_mult (a.get_type (), a, b);
+}
+inline rvalue operator/ (rvalue a, rvalue b)
+{
+  return a.get_context ().new_divide (a.get_type (), a, b);
+}
+inline rvalue operator% (rvalue a, rvalue b)
+{
+  return a.get_context ().new_modulo (a.get_type (), a, b);
+}
+inline rvalue operator& (rvalue a, rvalue b)
+{
+  return a.get_context ().new_bitwise_and (a.get_type (), a, b);
+}
+inline rvalue operator^ (rvalue a, rvalue b)
+{
+  return a.get_context ().new_bitwise_xor (a.get_type (), a, b);
+}
+inline rvalue operator| (rvalue a, rvalue b)
+{
+  return a.get_context ().new_bitwise_or (a.get_type (), a, b);
+}
+inline rvalue operator&& (rvalue a, rvalue b)
+{
+  return a.get_context ().new_logical_and (a.get_type (), a, b);
+}
+inline rvalue operator|| (rvalue a, rvalue b)
+{
+  return a.get_context ().new_logical_or (a.get_type (), a, b);
+}
+
+/* Comparisons.  */
+inline rvalue operator== (rvalue a, rvalue b)
+{
+  return a.get_context ().new_eq (a, b);
+}
+inline rvalue operator!= (rvalue a, rvalue b)
+{
+  return a.get_context ().new_ne (a, b);
+}
+inline rvalue operator< (rvalue a, rvalue b)
+{
+  return a.get_context ().new_lt (a, b);
+}
+inline rvalue operator<= (rvalue a, rvalue b)
+{
+  return a.get_context ().new_le (a, b);
+}
+inline rvalue operator> (rvalue a, rvalue b)
+{
+  return a.get_context ().new_gt (a, b);
+}
+inline rvalue operator>= (rvalue a, rvalue b)
+{
+  return a.get_context ().new_ge (a, b);
+}
+
+/* Dereferencing. */
+inline lvalue operator* (rvalue ptr)
+{
+  return ptr.dereference ();
+}
+
 } // namespace gccjit
 
 #endif /* #ifndef LIBGCCJIT_PLUS_PLUS_H */
diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c
index 181954d..3f39984 100644
--- a/gcc/jit/libgccjit.c
+++ b/gcc/jit/libgccjit.c
@@ -452,6 +452,14 @@ gcc_jit_rvalue_as_object (gcc_jit_rvalue *rvalue)
   return static_cast <gcc_jit_object *> (rvalue->as_object ());
 }
 
+gcc_jit_type *
+gcc_jit_rvalue_get_type (gcc_jit_rvalue *rvalue)
+{
+  RETURN_NULL_IF_FAIL (rvalue, NULL, "NULL rvalue");
+
+  return static_cast <gcc_jit_type *> (rvalue->get_type ());
+}
+
 gcc_jit_rvalue *
 gcc_jit_context_new_rvalue_from_int (gcc_jit_context *ctxt,
 				     gcc_jit_type *numeric_type,
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index 1ef55d0..e0161ba 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -467,6 +467,9 @@ gcc_jit_lvalue_as_rvalue (gcc_jit_lvalue *lvalue);
 extern gcc_jit_object *
 gcc_jit_rvalue_as_object (gcc_jit_rvalue *rvalue);
 
+extern gcc_jit_type *
+gcc_jit_rvalue_get_type (gcc_jit_rvalue *rvalue);
+
 /* Integer constants. */
 extern gcc_jit_rvalue *
 gcc_jit_context_new_rvalue_from_int (gcc_jit_context *ctxt,
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
index cbf9b33..6dc700d 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -63,6 +63,7 @@
     gcc_jit_rvalue_as_object;
     gcc_jit_rvalue_dereference;
     gcc_jit_rvalue_dereference_field;
+    gcc_jit_rvalue_get_type;
     gcc_jit_type_as_object;
     gcc_jit_type_get_const;
     gcc_jit_type_get_pointer;
diff --git a/gcc/testsuite/ChangeLog.jit b/gcc/testsuite/ChangeLog.jit
index ee2dc40..11987e0 100644
--- a/gcc/testsuite/ChangeLog.jit
+++ b/gcc/testsuite/ChangeLog.jit
@@ -1,5 +1,10 @@
 2014-02-10  David Malcolm  <dmalcolm@redhat.com>
 
+	* jit.dg/test-operator-overloading.cc: New testcase, a
+	rewrite of test-quadratic.cc to use operator overloading.
+
+2014-02-10  David Malcolm  <dmalcolm@redhat.com>
+
 	* jit.dg/test-quadratic.cc (make_calc_discriminant): Make use of
 	new methods of the C++ wrapper API to shorten the example code.
 	(make_test_quadratic): Likewise.
diff --git a/gcc/testsuite/jit.dg/test-operator-overloading.cc b/gcc/testsuite/jit.dg/test-operator-overloading.cc
new file mode 100644
index 0000000..313b3e6
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-operator-overloading.cc
@@ -0,0 +1,306 @@
+/* Test of C++ API.  */
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit++.h"
+
+#include <sstream>
+
+#include "harness.h"
+
+struct quadratic
+{
+  double a;
+  double b;
+  double c;
+  double discriminant;
+};
+
+/* As per test-quadratic.cc, let's try to inject the equivalent of:
+
+     extern double sqrt (double);
+
+     void
+     calc_discriminant (struct quadratic *q)
+     {
+       // (b^2 - 4ac)
+       q->discriminant = (q->b * q->b) - (4 * q->a * q->c);
+     }
+
+     int
+     test_quadratic (double a, double b, double c, double *r1, double *r2)
+     {
+       struct quadratic q;
+       q.a = a;
+       q.b = b;
+       q.c = c;
+       calc_discriminant (&q);
+       if (q.discriminant > 0)
+	 {
+	    double s = sqrt (q.discriminant);
+	    *r1 = (-b + s) / (2 * a);
+	    *r2 = (-b - s) / (2 * a);
+	    return 2;
+	 }
+       else if (q.discriminant == 0)
+	 {
+	    *r1 = -b / (2 * a);
+	    return 1;
+	 }
+	 else return 0;
+     }
+
+  However, we'll use operator overloading for maxium brevity, at the
+  risk of perhaps being too "magical".
+*/
+
+/****************************************************************************
+ Test case
+ ****************************************************************************/
+
+struct quadratic_test
+{
+  gccjit::context ctxt;
+
+  /* "double" and "(double *)".  */
+  gccjit::type numeric_type;
+  gccjit::type numeric_type_ptr;
+
+  /* The value (double)0.  */
+  gccjit::rvalue zero;
+
+  gccjit::type int_type;
+
+  /* "struct quadratic" */
+  gccjit::type quadratic;
+  gccjit::field a;
+  gccjit::field b;
+  gccjit::field c;
+  gccjit::field discriminant;
+
+  /* "(struct quadratic *)" */
+  gccjit::type quadratic_ptr;
+
+  gccjit::function calc_discriminant;
+
+  gccjit::function sqrt;
+
+};
+
+static void
+make_types (quadratic_test &testcase)
+{
+  testcase.numeric_type = testcase.ctxt.get_type (GCC_JIT_TYPE_DOUBLE);
+  testcase.numeric_type_ptr = testcase.numeric_type.get_pointer ();
+  testcase.zero = testcase.ctxt.zero (testcase.numeric_type);
+
+  testcase.int_type = testcase.ctxt.get_type (GCC_JIT_TYPE_INT);
+
+  testcase.a = testcase.ctxt.new_field (testcase.numeric_type, "a");
+  testcase.b = testcase.ctxt.new_field (testcase.numeric_type, "b");
+  testcase.c = testcase.ctxt.new_field (testcase.numeric_type, "c");
+  testcase.discriminant =
+    testcase.ctxt.new_field (testcase.numeric_type, "discriminant");
+  CHECK_STRING_VALUE (testcase.discriminant.get_debug_string ().c_str (),
+                      "discriminant");
+  std::vector<gccjit::field> fields (4);
+  fields[0] = testcase.a;
+  fields[1] = testcase.b;
+  fields[2] = testcase.c;
+  fields[3] = testcase.discriminant;
+  testcase.quadratic =
+    testcase.ctxt.new_struct_type (
+      "quadratic",
+      fields);
+  testcase.quadratic_ptr = testcase.quadratic.get_pointer ();
+}
+
+static void
+make_sqrt (quadratic_test &testcase)
+{
+  std::vector<gccjit::param> params (1);
+  params[0] =
+    testcase.ctxt.new_param (testcase.numeric_type, "x");
+  testcase.sqrt =
+    testcase.ctxt.new_function (GCC_JIT_FUNCTION_IMPORTED,
+				testcase.numeric_type,
+				"sqrt",
+				params,
+				0);
+}
+
+static void
+make_calc_discriminant (quadratic_test &testcase)
+{
+  /* Build "calc_discriminant".  */
+  gccjit::param param_q =
+    testcase.ctxt.new_param (testcase.quadratic_ptr, "q");
+  std::vector <gccjit::param> params (1);
+  params[0] = param_q;
+  testcase.calc_discriminant =
+    testcase.ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
+				testcase.numeric_type,
+				"calc_discriminant",
+				params,
+				0);
+  testcase.calc_discriminant.add_comment ("(b^2 - 4ac)");
+
+  gccjit::rvalue q_a = param_q.dereference_field (testcase.a);
+  gccjit::rvalue q_b = param_q.dereference_field (testcase.b);
+  gccjit::rvalue q_c = param_q.dereference_field (testcase.c);
+
+  gccjit::rvalue four =
+    testcase.ctxt.new_rvalue (testcase.numeric_type, 4);
+
+  testcase.calc_discriminant.add_assignment (
+    /* q->discriminant =...  */
+    param_q.dereference_field (testcase.discriminant),
+    /* (q->b * q->b) - (4 * q->a * q->c) */
+    (q_b * q_b) - (four * q_a * q_c));
+}
+
+static void
+make_test_quadratic (quadratic_test &testcase)
+{
+  gccjit::param a = testcase.ctxt.new_param (testcase.numeric_type, "a");
+  gccjit::param b = testcase.ctxt.new_param (testcase.numeric_type, "b");
+  gccjit::param c = testcase.ctxt.new_param (testcase.numeric_type, "c");
+  gccjit::param r1 =
+    testcase.ctxt.new_param (testcase.numeric_type_ptr, "r1");
+  gccjit::param r2 =
+    testcase.ctxt.new_param (testcase.numeric_type_ptr, "r2");
+
+  std::vector<gccjit::param> params (5);
+  params[0] = a;
+  params[1] = b;
+  params[2] = c;
+  params[3] = r1;
+  params[4] = r2;
+
+  gccjit::function test_quadratic =
+    testcase.ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
+				testcase.int_type,
+				"test_quadratic",
+				params,
+				0);
+
+  /* struct quadratic q; */
+  gccjit::lvalue q = test_quadratic.new_local (testcase.quadratic, "q");
+  /* q.a = a; */
+  test_quadratic.add_assignment (q.access_field (testcase.a), a);
+  /* q.b = b; */
+  test_quadratic.add_assignment (q.access_field (testcase.b), b);
+  /* q.c = c; */
+  test_quadratic.add_assignment (q.access_field (testcase.c), c);
+  /* calc_discriminant (&q); */
+  gccjit::rvalue address_of_q = q.get_address ();
+  test_quadratic.add_eval (testcase.calc_discriminant (address_of_q));
+
+  gccjit::label on_positive_discriminant
+    = test_quadratic.new_forward_label ("positive_discriminant");
+
+  gccjit::label on_nonpositive_discriminant
+    = test_quadratic.new_forward_label ("nonpositive_discriminant");
+
+  gccjit::label on_zero_discriminant
+    = test_quadratic.new_forward_label ("zero_discriminant");
+
+  gccjit::label on_negative_discriminant
+    = test_quadratic.new_forward_label ("negative_discriminant");
+  CHECK_STRING_VALUE (on_zero_discriminant.get_debug_string ().c_str (),
+                      "zero_discriminant");
+
+  test_quadratic.add_comment ("if (q.discriminant > 0)");
+  test_quadratic.add_conditional (
+    q.access_field (testcase.discriminant) > testcase.zero,
+    on_positive_discriminant,
+    on_nonpositive_discriminant);
+
+  test_quadratic.place_forward_label (on_positive_discriminant);
+  /* double s = sqrt (q.discriminant); */
+  gccjit::lvalue s = test_quadratic.new_local (testcase.numeric_type, "s");
+  gccjit::rvalue discriminant_of_q = q.access_field (testcase.discriminant);
+  test_quadratic.add_assignment (s, testcase.sqrt (discriminant_of_q));
+
+  gccjit::rvalue minus_b = -b;
+  gccjit::rvalue two =
+    testcase.ctxt.new_rvalue (testcase.numeric_type, 2);
+  gccjit::rvalue two_a = two * a;
+  CHECK_STRING_VALUE (two_a.get_debug_string ().c_str (),
+                      "(double)2 * a");
+
+  test_quadratic.add_comment ("*r1 = (-b + s) / (2 * a);");
+  test_quadratic.add_assignment (*r1, (minus_b + s) / two_a);
+
+  test_quadratic.add_comment ("*r2 = (-b - s) / (2 * a)");
+  test_quadratic.add_assignment (*r2, (minus_b - s) / two_a);
+
+  /* "return 2;" */
+  test_quadratic.add_return (testcase.ctxt.new_rvalue (testcase.int_type, 2));
+
+  /* "else if (q.discriminant == 0)" */
+  test_quadratic.place_forward_label (on_nonpositive_discriminant);
+  test_quadratic.add_comment ("else if (q.discriminant == 0)");
+  test_quadratic.add_conditional (
+    q.access_field (testcase.discriminant) == testcase.zero,
+    on_zero_discriminant,
+    on_negative_discriminant);
+
+  /* if (q.discriminant == 0) */
+  test_quadratic.place_forward_label (on_zero_discriminant);
+
+  test_quadratic.add_comment ("*r1 = -b / (2 * a);");
+  test_quadratic.add_assignment (*r1, minus_b / two_a);
+
+  /* "return 1;" */
+  test_quadratic.add_return (testcase.ctxt.one (testcase.int_type));
+
+  /* else return 0; */
+  test_quadratic.place_forward_label (on_negative_discriminant);
+  test_quadratic.add_return (testcase.ctxt.zero (testcase.int_type));
+
+  /* Verify that output stream operator << works.  */
+  std::ostringstream os;
+  os << "streamed output: " << address_of_q;
+  CHECK_STRING_VALUE (os.str ().c_str (), "streamed output: &q");
+}
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+  struct quadratic_test testcase;
+  memset (&testcase, 0, sizeof (testcase));
+  testcase.ctxt = ctxt;
+  make_types (testcase);
+  make_sqrt (testcase);
+  make_calc_discriminant (testcase);
+  make_test_quadratic (testcase);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+  typedef int (*fn_type) (double a, double b, double c,
+			  double *r1, double *r2);
+
+  CHECK_NON_NULL (result);
+
+  fn_type test_quadratic =
+    (fn_type)gcc_jit_result_get_code (result, "test_quadratic");
+  CHECK_NON_NULL (test_quadratic);
+
+  /* Verify that the code correctly solves quadratic equations.  */
+  double r1, r2;
+
+  /* This one has two solutions: */
+  CHECK_VALUE (test_quadratic (1, 3, -4, &r1, &r2), 2);
+  CHECK_VALUE (r1, 1);
+  CHECK_VALUE (r2, -4);
+
+  /* This one has one solution: */
+  CHECK_VALUE (test_quadratic (4, 4, 1, &r1, &r2), 1);
+  CHECK_VALUE (r1, -0.5);
+
+  /* This one has no real solutions: */
+  CHECK_VALUE (test_quadratic (4, 1, 1, &r1, &r2), 0);
+}
-- 
1.7.11.7


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]