@@ -1,5 +1,19 @@
2014-02-10 David Malcolm <dmalcolm@redhat.com>
+ * libgccjit.h (gcc_jit_context_get_int_type): New.
+ * libgccjit.map (gcc_jit_context_get_int_type): New.
+ * libgccjit.c (gcc_jit_context_get_int_type): New.
+
+ * internal-api.h (gcc::jit::recording::context::get_int_type): New.
+ (gcc::jit::recording::context::get_int_type<T>): New template.
+ * internal-api.c (gcc::jit::recording::context::get_int_type): New.
+
+ * libgccjit++.h: Include <limits> so we can use std::numeric_limits.
+ (gccjit::context::get_int_type): New.
+ (gccjit::context::get_int_type<T>): New.
+
+2014-02-10 David Malcolm <dmalcolm@redhat.com>
+
* libgccjit.h (gcc_jit_function_get_param): New.
* libgccjit.map (gcc_jit_function_get_param): New.
* libgccjit.c (gcc_jit_function_get_param): New.
@@ -215,6 +215,43 @@ recording::context::get_type (enum gcc_jit_types kind)
}
recording::type *
+recording::context::get_int_type (int num_bytes, int is_signed)
+{
+ /* We can't use a switch here since some of the values are macros affected
+ by options; e.g. i386.h has
+ #define LONG_TYPE_SIZE (TARGET_X32 ? 32 : BITS_PER_WORD)
+ Compare with tree.c's make_or_reuse_type. Note that the _SIZE macros
+ are in bits, rather than bytes.
+ */
+ const int num_bits = num_bytes * 8;
+ if (num_bits == INT_TYPE_SIZE)
+ return get_type (is_signed
+ ? GCC_JIT_TYPE_INT
+ : GCC_JIT_TYPE_UNSIGNED_INT);
+ if (num_bits == CHAR_TYPE_SIZE)
+ return get_type (is_signed
+ ? GCC_JIT_TYPE_SIGNED_CHAR
+ : GCC_JIT_TYPE_UNSIGNED_CHAR);
+ if (num_bits == SHORT_TYPE_SIZE)
+ return get_type (is_signed
+ ? GCC_JIT_TYPE_SHORT
+ : GCC_JIT_TYPE_UNSIGNED_SHORT);
+ if (num_bits == LONG_TYPE_SIZE)
+ return get_type (is_signed
+ ? GCC_JIT_TYPE_LONG
+ : GCC_JIT_TYPE_UNSIGNED_LONG);
+ if (num_bits == LONG_LONG_TYPE_SIZE)
+ return get_type (is_signed
+ ? GCC_JIT_TYPE_LONG_LONG
+ : GCC_JIT_TYPE_UNSIGNED_LONG_LONG);
+
+ /* Some other size, not corresponding to the C int types. */
+ /* To be written: support arbitrary other sizes, sharing by
+ memoizing at the recording::context level? */
+ gcc_unreachable ();
+}
+
+recording::type *
recording::context::new_array_type (recording::location *loc,
recording::type *element_type,
int num_elements)
@@ -143,6 +143,9 @@ public:
get_type (enum gcc_jit_types type);
type *
+ get_int_type (int num_bytes, int is_signed);
+
+ type *
new_array_type (location *loc,
type *element_type,
int num_elements);
@@ -5,6 +5,7 @@
#include "libgccjit.h"
+#include <limits>
#include <ostream>
#include <vector>
@@ -82,6 +83,13 @@ namespace gccjit
int column);
type get_type (enum gcc_jit_types kind);
+ type get_int_type (size_t num_bytes, int is_signed);
+
+ /* A way to map a specific int type, using the compiler to
+ get the details automatically e.g.:
+ gccjit::type type = get_int_type <my_int_type_t> (); */
+ template <typename T>
+ type get_int_type ();
type new_array_type (type element_type, int num_elements,
location loc = location ());
@@ -465,6 +473,21 @@ context::get_type (enum gcc_jit_types kind)
}
inline type
+context::get_int_type (size_t num_bytes, int is_signed)
+{
+ return type (gcc_jit_context_get_int_type (m_inner_ctxt,
+ num_bytes,
+ is_signed));
+}
+
+template <typename T>
+inline type
+context::get_int_type ()
+{
+ return get_int_type (sizeof (T), std::numeric_limits<T>::is_signed);
+}
+
+inline type
context::new_array_type (type element_type, int num_elements, location loc)
{
return type (gcc_jit_context_new_array_type (
@@ -246,6 +246,16 @@ gcc_jit_context_get_type (gcc_jit_context *ctxt,
}
gcc_jit_type *
+gcc_jit_context_get_int_type (gcc_jit_context *ctxt,
+ int num_bytes, int is_signed)
+{
+ RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
+ RETURN_NULL_IF_FAIL (num_bytes >= 0, ctxt, "negative size");
+
+ return (gcc_jit_type *)ctxt->get_int_type (num_bytes, is_signed);
+}
+
+gcc_jit_type *
gcc_jit_type_get_pointer (gcc_jit_type *type)
{
RETURN_NULL_IF_FAIL (type, NULL, "NULL type");
@@ -349,6 +349,10 @@ extern gcc_jit_type *
gcc_jit_context_get_type (gcc_jit_context *ctxt,
enum gcc_jit_types type_);
+extern gcc_jit_type *
+gcc_jit_context_get_int_type (gcc_jit_context *ctxt,
+ int num_bytes, int is_signed);
+
/* Constructing new types. */
/* Given type "T", get type "T*". */
@@ -6,6 +6,7 @@
gcc_jit_context_compile;
gcc_jit_context_get_first_error;
gcc_jit_context_get_type;
+ gcc_jit_context_get_int_type;
gcc_jit_context_new_array_access;
gcc_jit_context_new_array_type;
gcc_jit_context_new_binary_op;
@@ -1,5 +1,16 @@
2014-02-10 David Malcolm <dmalcolm@redhat.com>
+ * jit.dg/test-types.c (struct zoo): Add field m_sized_int_type,
+ to be populated by...
+ (create_code): Use gcc_jit_context_get_int_type.
+ (verify_code): Verify that type from gcc_jit_context_get_int_type
+ works properly.
+ * jit.dg/test-operator-overloading.cc (make_types): Use the
+ template form of get_int_type.
+ * jit.dg/test-quadratic.cc (make_types): Likewise.
+
+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.
@@ -94,7 +94,7 @@ make_types (quadratic_test &testcase)
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.int_type = testcase.ctxt.get_int_type <int> ();
testcase.a = testcase.ctxt.new_field (testcase.numeric_type, "a");
testcase.b = testcase.ctxt.new_field (testcase.numeric_type, "b");
@@ -93,7 +93,7 @@ make_types (quadratic_test &testcase)
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.int_type = testcase.ctxt.get_int_type <int> ();
testcase.a = testcase.ctxt.new_field (testcase.numeric_type, "a");
testcase.b = testcase.ctxt.new_field (testcase.numeric_type, "b");
@@ -26,6 +26,8 @@ struct zoo
long long m_long_long;
unsigned long long m_unsigned_long_long;
+ int m_sized_int_type;
+
float m_float;
double m_double;
long double m_long_double;
@@ -93,6 +95,13 @@ create_code (gcc_jit_context *ctxt, void *user_data)
gcc_jit_field *field_m_unsigned_long_long =
CREATE_FIELD (GCC_JIT_TYPE_UNSIGNED_LONG_LONG, "m_unsigned_long_long");
+ /* Signed int type with sizeof (int): */
+ gcc_jit_type *sized_int_type =
+ gcc_jit_context_get_int_type (ctxt, sizeof (int), 1);
+ gcc_jit_field *field_m_sized_int_type =
+ gcc_jit_context_new_field (
+ ctxt, NULL, sized_int_type, "m_sized_int_type");
+
gcc_jit_field *field_m_float =
CREATE_FIELD (GCC_JIT_TYPE_FLOAT, "m_float");
gcc_jit_field *field_m_double =
@@ -130,6 +139,8 @@ create_code (gcc_jit_context *ctxt, void *user_data)
field_m_long_long,
field_m_unsigned_long_long,
+ field_m_sized_int_type,
+
field_m_float,
field_m_double,
field_m_long_double,
@@ -240,6 +251,11 @@ create_code (gcc_jit_context *ctxt, void *user_data)
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UNSIGNED_LONG_LONG),
123456789))
+ ASSIGN(field_m_sized_int_type,
+ gcc_jit_context_new_rvalue_from_int (
+ ctxt,
+ sized_int_type, 500))
+
ASSIGN(field_m_float,
gcc_jit_context_new_rvalue_from_double (
ctxt,
@@ -312,6 +328,8 @@ verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
CHECK_VALUE (z.m_long_long, -42);
CHECK_VALUE (z.m_unsigned_long_long, 123456789);
+ CHECK_VALUE (z.m_sized_int_type, 500);
+
CHECK_VALUE (z.m_float, 3.141f);
CHECK_VALUE (z.m_double, 3.141);
CHECK_VALUE (z.m_long_double, 3.141);