From db8836d1e16e432b6f40a26549648f6477d491bc Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Mon, 10 May 2021 19:43:02 -0400 Subject: [PATCH] libgccjit: Add support for sized integer types, including 128-bit integers [PR95325] 2022-01-19 Antoni Boucher gcc/jit/ PR target/95325 * docs/topics/compatibility.rst (LIBGCCJIT_ABI_20): New ABI tag. * docs/topics/types.rst: Add documentation for the new types GCC_JIT_TYPE_UINT8_T, GCC_JIT_TYPE_UINT16_T, GCC_JIT_TYPE_UINT32_T, GCC_JIT_TYPE_UINT64_T, GCC_JIT_TYPE_UINT128_T, GCC_JIT_TYPE_INT8_T, GCC_JIT_TYPE_INT16_T, GCC_JIT_TYPE_INT32_T, GCC_JIT_TYPE_INT64_T, GCC_JIT_TYPE_INT128_T and new functions (gcc_jit_compatible_types, gcc_jit_type_get_size). * jit-builtins.cc: Add support for BT_UINT128. * jit-common.h: Update the value of NUM_GCC_JIT_TYPES. * jit-playback.cc: Add support for the sized integer types. * jit-recording.cc: Add support for the sized integer types. * jit-recording.h: Add support for comparing integer types and new function (is_signed). * libgccjit.cc: Rename compatible_types to gcc_jit_compatible_types and new function (gcc_jit_type_get_size). * libgccjit.h: New enum variants for gcc_jit_types (GCC_JIT_TYPE_UINT8_T, GCC_JIT_TYPE_UINT16_T, GCC_JIT_TYPE_UINT32_T, GCC_JIT_TYPE_UINT64_T, GCC_JIT_TYPE_UINT128_T, GCC_JIT_TYPE_INT8_T, GCC_JIT_TYPE_INT16_T, GCC_JIT_TYPE_INT32_T, GCC_JIT_TYPE_INT64_T, GCC_JIT_TYPE_INT128_T) and new functions (gcc_jit_compatible_types, gcc_jit_type_get_size). libgccjit.map (LIBGCCJIT_ABI_20): New ABI tag. gcc/testsuite/ PR target/95325 * jit.dg/test-types.c: Add tests for sized integer types. --- gcc/jit/docs/topics/compatibility.rst | 20 ++++ gcc/jit/docs/topics/types.rst | 41 ++++++++ gcc/jit/jit-builtins.cc | 1 + gcc/jit/jit-common.h | 2 +- gcc/jit/jit-playback.cc | 37 ++++++- gcc/jit/jit-recording.cc | 146 +++++++++++++++++++++++++- gcc/jit/jit-recording.h | 16 +++ gcc/jit/libgccjit.cc | 52 +++++---- gcc/jit/libgccjit.h | 32 +++++- gcc/jit/libgccjit.map | 6 ++ gcc/testsuite/jit.dg/test-types.c | 131 +++++++++++++++++++++++ 11 files changed, 457 insertions(+), 27 deletions(-) diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst index 16cebe31a10..73a17664698 100644 --- a/gcc/jit/docs/topics/compatibility.rst +++ b/gcc/jit/docs/topics/compatibility.rst @@ -302,3 +302,23 @@ thread-local storage model of a variable: section of a variable: * :func:`gcc_jit_lvalue_set_link_section` + +.. _LIBGCCJIT_ABI_20: + +``LIBGCCJIT_ABI_20`` +----------------------- +``LIBGCCJIT_ABI_20`` covers the addition of sized integer types, including +128-bit integers and helper functions for types: + + * :func:`gcc_jit_compatible_types` + * :func:`gcc_jit_type_get_size` + * :c:macro:`GCC_JIT_TYPE_UINT8_T` + * :c:macro:`GCC_JIT_TYPE_UINT16_T` + * :c:macro:`GCC_JIT_TYPE_UINT32_T` + * :c:macro:`GCC_JIT_TYPE_UINT64_T` + * :c:macro:`GCC_JIT_TYPE_UINT128_T` + * :c:macro:`GCC_JIT_TYPE_INT8_T` + * :c:macro:`GCC_JIT_TYPE_INT16_T` + * :c:macro:`GCC_JIT_TYPE_INT32_T` + * :c:macro:`GCC_JIT_TYPE_INT64_T` + * :c:macro:`GCC_JIT_TYPE_INT128_T` diff --git a/gcc/jit/docs/topics/types.rst b/gcc/jit/docs/topics/types.rst index 9779ad26b6f..ededf49e149 100644 --- a/gcc/jit/docs/topics/types.rst +++ b/gcc/jit/docs/topics/types.rst @@ -76,6 +76,16 @@ Standard types :c:data:`GCC_JIT_TYPE_UNSIGNED_LONG` C's ``unsigned long`` :c:data:`GCC_JIT_TYPE_LONG_LONG` C99's ``long long`` (signed) :c:data:`GCC_JIT_TYPE_UNSIGNED_LONG_LONG` C99's ``unsigned long long`` + :c:data:`GCC_JIT_TYPE_UINT8_T` C99's ``uint8_t`` + :c:data:`GCC_JIT_TYPE_UINT16_T` C99's ``uint16_t`` + :c:data:`GCC_JIT_TYPE_UINT32_T` C99's ``uint32_t`` + :c:data:`GCC_JIT_TYPE_UINT64_T` C99's ``uint64_t`` + :c:data:`GCC_JIT_TYPE_UINT128_T` C99's ``__uint128_t`` + :c:data:`GCC_JIT_TYPE_INT8_T` C99's ``int8_t`` + :c:data:`GCC_JIT_TYPE_INT16_T` C99's ``int16_t`` + :c:data:`GCC_JIT_TYPE_INT32_T` C99's ``int32_t`` + :c:data:`GCC_JIT_TYPE_INT64_T` C99's ``int64_t`` + :c:data:`GCC_JIT_TYPE_INT128_T` C99's ``__int128_t`` :c:data:`GCC_JIT_TYPE_FLOAT` :c:data:`GCC_JIT_TYPE_DOUBLE` :c:data:`GCC_JIT_TYPE_LONG_DOUBLE` @@ -467,3 +477,34 @@ Reflection API #ifdef LIBGCCJIT_HAVE_REFLECTION .. type:: gcc_jit_case + +.. function:: int\ + gcc_jit_compatible_types (gcc_jit_type *ltype, + gcc_jit_type *rtype) + + Return non-zero if the two types are compatible. For instance, + if :c:data:`GCC_JIT_TYPE_UINT64_T` and :c:data:`GCC_JIT_TYPE_UNSIGNED_LONG` + are the same size on the target, this will return non-zero. + The parameters ``ltype`` and ``rtype`` must be non-NULL. + Return 0 on errors. + + This entrypoint was added in :ref:`LIBGCCJIT_ABI_20`; you can test for + its presence using + + .. code-block:: c + + #ifdef LIBGCCJIT_HAVE_SIZED_INTEGERS + +.. function:: ssize_t\ + gcc_jit_type_get_size (gcc_jit_type *type) + + Return the size of a type, in bytes. It only works on integer types for now. + The parameter ``type`` must be non-NULL. + Return -1 on errors. + + This entrypoint was added in :ref:`LIBGCCJIT_ABI_20`; you can test for + its presence using + + .. code-block:: c + + #ifdef LIBGCCJIT_HAVE_SIZED_INTEGERS diff --git a/gcc/jit/jit-builtins.cc b/gcc/jit/jit-builtins.cc index 71c38eb0948..b949b734332 100644 --- a/gcc/jit/jit-builtins.cc +++ b/gcc/jit/jit-builtins.cc @@ -483,6 +483,7 @@ builtins_manager::make_primitive_type (enum jit_builtin_type type_id) case BT_UINT16: return m_ctxt->get_int_type (2, false); case BT_UINT32: return m_ctxt->get_int_type (4, false); case BT_UINT64: return m_ctxt->get_int_type (8, false); + case BT_UINT128: return m_ctxt->get_int_type (16, false); // case BT_WORD: // case BT_UNWINDWORD: case BT_FLOAT: return m_ctxt->get_type (GCC_JIT_TYPE_FLOAT); diff --git a/gcc/jit/jit-common.h b/gcc/jit/jit-common.h index 1a8cd8bac7b..8c52ddf80e1 100644 --- a/gcc/jit/jit-common.h +++ b/gcc/jit/jit-common.h @@ -36,7 +36,7 @@ along with GCC; see the file COPYING3. If not see #endif #endif -const int NUM_GCC_JIT_TYPES = GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE + 1; +const int NUM_GCC_JIT_TYPES = GCC_JIT_TYPE_INT128_T + 1; /* This comment is included by the docs. diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc index d1835c79863..4683e862611 100644 --- a/gcc/jit/jit-playback.cc +++ b/gcc/jit/jit-playback.cc @@ -237,6 +237,36 @@ get_tree_node_for_type (enum gcc_jit_types type_) case GCC_JIT_TYPE_UNSIGNED_INT: return unsigned_type_node; + case GCC_JIT_TYPE_UINT8_T: + return unsigned_intQI_type_node; + case GCC_JIT_TYPE_UINT16_T: + return uint16_type_node; + case GCC_JIT_TYPE_UINT32_T: + return uint32_type_node; + case GCC_JIT_TYPE_UINT64_T: + return uint64_type_node; + case GCC_JIT_TYPE_UINT128_T: + if (targetm.scalar_mode_supported_p (TImode)) + return uint128_type_node; + + add_error (NULL, "gcc_jit_types value unsupported on this target: %i", type_); + return NULL; + + case GCC_JIT_TYPE_INT8_T: + return intQI_type_node; + case GCC_JIT_TYPE_INT16_T: + return intHI_type_node; + case GCC_JIT_TYPE_INT32_T: + return intSI_type_node; + case GCC_JIT_TYPE_INT64_T: + return intDI_type_node; + case GCC_JIT_TYPE_INT128_T: + if (targetm.scalar_mode_supported_p (TImode)) + return intTI_type_node; + + add_error (NULL, "gcc_jit_types value unsupported on this target: %i", type_); + return NULL; + case GCC_JIT_TYPE_LONG: return long_integer_type_node; case GCC_JIT_TYPE_UNSIGNED_LONG: @@ -268,6 +298,8 @@ get_tree_node_for_type (enum gcc_jit_types type_) return complex_long_double_type_node; } + add_error (NULL, "unrecognized (enum gcc_jit_types) value: %i", type_); + return NULL; } @@ -280,10 +312,7 @@ get_type (enum gcc_jit_types type_) { tree type_node = get_tree_node_for_type (type_); if (type_node == NULL) - { - add_error (NULL, "unrecognized (enum gcc_jit_types) value: %i", type_); - return NULL; - } + return NULL; return new type (type_node); } diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc index 1e3fadfacd7..4ffdad0665f 100644 --- a/gcc/jit/jit-recording.cc +++ b/gcc/jit/jit-recording.cc @@ -822,6 +822,10 @@ recording::context::get_int_type (int num_bytes, int is_signed) return get_type (is_signed ? GCC_JIT_TYPE_LONG_LONG : GCC_JIT_TYPE_UNSIGNED_LONG_LONG); + if (num_bits == 128) + return get_type (is_signed + ? GCC_JIT_TYPE_INT128_T + : GCC_JIT_TYPE_UINT128_T); /* Some other size, not corresponding to the C int types. */ /* To be written: support arbitrary other sizes, sharing by @@ -2325,6 +2329,26 @@ recording::memento_of_get_type::get_size () case GCC_JIT_TYPE_UNSIGNED_LONG_LONG: size = LONG_LONG_TYPE_SIZE; break; + case GCC_JIT_TYPE_UINT8_T: + case GCC_JIT_TYPE_INT8_T: + size = 8; + break; + case GCC_JIT_TYPE_UINT16_T: + case GCC_JIT_TYPE_INT16_T: + size = 16; + break; + case GCC_JIT_TYPE_UINT32_T: + case GCC_JIT_TYPE_INT32_T: + size = 32; + break; + case GCC_JIT_TYPE_UINT64_T: + case GCC_JIT_TYPE_INT64_T: + size = 64; + break; + case GCC_JIT_TYPE_UINT128_T: + case GCC_JIT_TYPE_INT128_T: + size = 128; + break; case GCC_JIT_TYPE_FLOAT: size = FLOAT_TYPE_SIZE; break; @@ -2334,6 +2358,9 @@ recording::memento_of_get_type::get_size () case GCC_JIT_TYPE_LONG_DOUBLE: size = LONG_DOUBLE_TYPE_SIZE; break; + case GCC_JIT_TYPE_SIZE_T: + size = MAX_BITS_PER_WORD; + break; default: /* As this function is called by 'gcc_jit_global_set_initializer' and @@ -2373,6 +2400,16 @@ recording::memento_of_get_type::dereference () case GCC_JIT_TYPE_UNSIGNED_LONG: case GCC_JIT_TYPE_LONG_LONG: case GCC_JIT_TYPE_UNSIGNED_LONG_LONG: + case GCC_JIT_TYPE_UINT8_T: + case GCC_JIT_TYPE_UINT16_T: + case GCC_JIT_TYPE_UINT32_T: + case GCC_JIT_TYPE_UINT64_T: + case GCC_JIT_TYPE_UINT128_T: + case GCC_JIT_TYPE_INT8_T: + case GCC_JIT_TYPE_INT16_T: + case GCC_JIT_TYPE_INT32_T: + case GCC_JIT_TYPE_INT64_T: + case GCC_JIT_TYPE_INT128_T: case GCC_JIT_TYPE_FLOAT: case GCC_JIT_TYPE_DOUBLE: case GCC_JIT_TYPE_LONG_DOUBLE: @@ -2425,6 +2462,16 @@ recording::memento_of_get_type::is_int () const case GCC_JIT_TYPE_UNSIGNED_LONG: case GCC_JIT_TYPE_LONG_LONG: case GCC_JIT_TYPE_UNSIGNED_LONG_LONG: + case GCC_JIT_TYPE_UINT8_T: + case GCC_JIT_TYPE_UINT16_T: + case GCC_JIT_TYPE_UINT32_T: + case GCC_JIT_TYPE_UINT64_T: + case GCC_JIT_TYPE_UINT128_T: + case GCC_JIT_TYPE_INT8_T: + case GCC_JIT_TYPE_INT16_T: + case GCC_JIT_TYPE_INT32_T: + case GCC_JIT_TYPE_INT64_T: + case GCC_JIT_TYPE_INT128_T: return true; case GCC_JIT_TYPE_FLOAT: @@ -2448,6 +2495,60 @@ recording::memento_of_get_type::is_int () const } } +/* Implementation of pure virtual hook recording::type::is_signed for + recording::memento_of_get_type. */ + +bool +recording::memento_of_get_type::is_signed () const +{ + switch (m_kind) + { + default: gcc_unreachable (); + + case GCC_JIT_TYPE_SIGNED_CHAR: + case GCC_JIT_TYPE_CHAR: + case GCC_JIT_TYPE_SHORT: + case GCC_JIT_TYPE_INT: + case GCC_JIT_TYPE_LONG: + case GCC_JIT_TYPE_LONG_LONG: + case GCC_JIT_TYPE_INT8_T: + case GCC_JIT_TYPE_INT16_T: + case GCC_JIT_TYPE_INT32_T: + case GCC_JIT_TYPE_INT64_T: + case GCC_JIT_TYPE_INT128_T: + return true; + + case GCC_JIT_TYPE_VOID: + case GCC_JIT_TYPE_VOID_PTR: + case GCC_JIT_TYPE_BOOL: + case GCC_JIT_TYPE_UNSIGNED_CHAR: + case GCC_JIT_TYPE_UNSIGNED_SHORT: + case GCC_JIT_TYPE_UNSIGNED_INT: + case GCC_JIT_TYPE_UNSIGNED_LONG: + case GCC_JIT_TYPE_UNSIGNED_LONG_LONG: + case GCC_JIT_TYPE_UINT8_T: + case GCC_JIT_TYPE_UINT16_T: + case GCC_JIT_TYPE_UINT32_T: + case GCC_JIT_TYPE_UINT64_T: + case GCC_JIT_TYPE_UINT128_T: + + case GCC_JIT_TYPE_FLOAT: + case GCC_JIT_TYPE_DOUBLE: + case GCC_JIT_TYPE_LONG_DOUBLE: + + case GCC_JIT_TYPE_CONST_CHAR_PTR: + + case GCC_JIT_TYPE_SIZE_T: + + case GCC_JIT_TYPE_FILE_PTR: + + case GCC_JIT_TYPE_COMPLEX_FLOAT: + case GCC_JIT_TYPE_COMPLEX_DOUBLE: + case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE: + return false; + } +} + /* Implementation of pure virtual hook recording::type::is_float for recording::memento_of_get_type. */ @@ -2478,6 +2579,16 @@ recording::memento_of_get_type::is_float () const case GCC_JIT_TYPE_UNSIGNED_LONG: case GCC_JIT_TYPE_LONG_LONG: case GCC_JIT_TYPE_UNSIGNED_LONG_LONG: + case GCC_JIT_TYPE_UINT8_T: + case GCC_JIT_TYPE_UINT16_T: + case GCC_JIT_TYPE_UINT32_T: + case GCC_JIT_TYPE_UINT64_T: + case GCC_JIT_TYPE_UINT128_T: + case GCC_JIT_TYPE_INT8_T: + case GCC_JIT_TYPE_INT16_T: + case GCC_JIT_TYPE_INT32_T: + case GCC_JIT_TYPE_INT64_T: + case GCC_JIT_TYPE_INT128_T: return false; case GCC_JIT_TYPE_FLOAT: @@ -2531,6 +2642,16 @@ recording::memento_of_get_type::is_bool () const case GCC_JIT_TYPE_UNSIGNED_LONG: case GCC_JIT_TYPE_LONG_LONG: case GCC_JIT_TYPE_UNSIGNED_LONG_LONG: + case GCC_JIT_TYPE_UINT8_T: + case GCC_JIT_TYPE_UINT16_T: + case GCC_JIT_TYPE_UINT32_T: + case GCC_JIT_TYPE_UINT64_T: + case GCC_JIT_TYPE_UINT128_T: + case GCC_JIT_TYPE_INT8_T: + case GCC_JIT_TYPE_INT16_T: + case GCC_JIT_TYPE_INT32_T: + case GCC_JIT_TYPE_INT64_T: + case GCC_JIT_TYPE_INT128_T: return false; case GCC_JIT_TYPE_FLOAT: @@ -2601,7 +2722,18 @@ static const char * const get_type_strings[] = { "complex float", /* GCC_JIT_TYPE_COMPLEX_FLOAT */ "complex double", /* GCC_JIT_TYPE_COMPLEX_DOUBLE */ - "complex long double" /* GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE */ + "complex long double", /* GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE */ + + "__uint8_t", /* GCC_JIT_TYPE_UINT8_T */ + "__uint16_t", /* GCC_JIT_TYPE_UINT16_T */ + "__uint32_t", /* GCC_JIT_TYPE_UINT32_T */ + "__uint64_t", /* GCC_JIT_TYPE_UINT64_T */ + "__uint128_t", /* GCC_JIT_TYPE_UINT128_T */ + "__int8_t", /* GCC_JIT_TYPE_INT8_T */ + "__int16_t", /* GCC_JIT_TYPE_INT16_T */ + "__int32_t", /* GCC_JIT_TYPE_INT32_T */ + "__int64_t", /* GCC_JIT_TYPE_INT64_T */ + "__int128_t", /* GCC_JIT_TYPE_INT128_T */ }; @@ -2637,7 +2769,17 @@ static const char * const get_type_enum_strings[] = { "GCC_JIT_TYPE_FILE_PTR", "GCC_JIT_TYPE_COMPLEX_FLOAT", "GCC_JIT_TYPE_COMPLEX_DOUBLE", - "GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE" + "GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE", + "GCC_JIT_TYPE_UINT8_T", + "GCC_JIT_TYPE_UINT16_T", + "GCC_JIT_TYPE_UINT32_T", + "GCC_JIT_TYPE_UINT64_T", + "GCC_JIT_TYPE_UINT128_T", + "GCC_JIT_TYPE_INT8_T", + "GCC_JIT_TYPE_INT16_T", + "GCC_JIT_TYPE_INT32_T", + "GCC_JIT_TYPE_INT64_T", + "GCC_JIT_TYPE_INT128_T", }; void diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h index 846d65cb202..1804aaa6664 100644 --- a/gcc/jit/jit-recording.h +++ b/gcc/jit/jit-recording.h @@ -564,6 +564,7 @@ public: virtual bool is_void () const { return false; } virtual vector_type *is_vector () { return NULL; } virtual bool has_known_size () const { return true; } + virtual bool is_signed () const = 0; bool is_numeric () const { @@ -604,12 +605,19 @@ public: bool accepts_writes_from (type *rtype) FINAL OVERRIDE { if (m_kind == GCC_JIT_TYPE_VOID_PTR) + { if (rtype->is_pointer ()) { /* LHS (this) is type (void *), and the RHS is a pointer: accept it: */ return true; } + } + else if (is_int () && rtype->is_int () && get_size () == rtype->get_size () && is_signed () == rtype->is_signed ()) + { + /* LHS (this) is an integer of the same size and sign as rtype. */ + return true; + } return type::accepts_writes_from (rtype); } @@ -620,6 +628,7 @@ public: type *is_pointer () FINAL OVERRIDE { return dereference (); } type *is_array () FINAL OVERRIDE { return NULL; } bool is_void () const FINAL OVERRIDE { return m_kind == GCC_JIT_TYPE_VOID; } + bool is_signed () const FINAL OVERRIDE; public: void replay_into (replayer *r) FINAL OVERRIDE; @@ -653,6 +662,7 @@ public: bool is_bool () const FINAL OVERRIDE { return false; } type *is_pointer () FINAL OVERRIDE { return m_other_type; } type *is_array () FINAL OVERRIDE { return NULL; } + bool is_signed () const FINAL OVERRIDE { return false; } private: string * make_debug_string () FINAL OVERRIDE; @@ -674,12 +684,15 @@ public: type *dereference () FINAL OVERRIDE { return m_other_type->dereference (); } + size_t get_size () FINAL OVERRIDE { return m_other_type->get_size (); }; + bool is_int () const FINAL OVERRIDE { return m_other_type->is_int (); } bool is_float () const FINAL OVERRIDE { return m_other_type->is_float (); } bool is_bool () const FINAL OVERRIDE { return m_other_type->is_bool (); } type *is_pointer () FINAL OVERRIDE { return m_other_type->is_pointer (); } type *is_array () FINAL OVERRIDE { return m_other_type->is_array (); } struct_ *is_struct () FINAL OVERRIDE { return m_other_type->is_struct (); } + bool is_signed () const FINAL OVERRIDE { return m_other_type->is_signed (); } protected: type *m_other_type; @@ -811,6 +824,7 @@ class array_type : public type type *is_pointer () FINAL OVERRIDE { return NULL; } type *is_array () FINAL OVERRIDE { return m_element_type; } int num_elements () { return m_num_elements; } + bool is_signed () const FINAL OVERRIDE { return false; } void replay_into (replayer *) FINAL OVERRIDE; @@ -844,6 +858,7 @@ public: bool is_bool () const FINAL OVERRIDE { return false; } type *is_pointer () FINAL OVERRIDE { return NULL; } type *is_array () FINAL OVERRIDE { return NULL; } + bool is_signed () const FINAL OVERRIDE { return false; } void replay_into (replayer *) FINAL OVERRIDE; @@ -957,6 +972,7 @@ public: bool is_bool () const FINAL OVERRIDE { return false; } type *is_pointer () FINAL OVERRIDE { return NULL; } type *is_array () FINAL OVERRIDE { return NULL; } + bool is_signed () const FINAL OVERRIDE { return false; } bool has_known_size () const FINAL OVERRIDE { return m_fields != NULL; } diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc index 4c352e8c93d..f09ba6c3e42 100644 --- a/gcc/jit/libgccjit.cc +++ b/gcc/jit/libgccjit.cc @@ -345,10 +345,12 @@ jit_error (gcc::jit::recording::context *ctxt, gcc::jit::recording::type::accepts_writes_from virtual function on LTYPE. */ -static bool -compatible_types (gcc::jit::recording::type *ltype, - gcc::jit::recording::type *rtype) +int +gcc_jit_compatible_types (gcc_jit_type *ltype, + gcc_jit_type *rtype) { + RETURN_VAL_IF_FAIL (ltype, 0, NULL, NULL, "NULL ltype"); + RETURN_VAL_IF_FAIL (rtype, 0, NULL, NULL, "NULL rtype"); return ltype->accepts_writes_from (rtype); } @@ -456,7 +458,7 @@ gcc_jit_context_get_type (gcc_jit_context *ctxt, JIT_LOG_FUNC (ctxt->get_logger ()); RETURN_NULL_IF_FAIL_PRINTF1 ( (type >= GCC_JIT_TYPE_VOID - && type <= GCC_JIT_TYPE_FILE_PTR), + && type < NUM_GCC_JIT_TYPES), ctxt, NULL, "unrecognized value for enum gcc_jit_types: %i", type); @@ -523,6 +525,20 @@ gcc_jit_type_get_volatile (gcc_jit_type *type) return (gcc_jit_type *)type->get_volatile (); } +/* Public entrypoint. See description in libgccjit.h. + + After error-checking, the real work is done by the + gcc::jit::recording::type::get_size method, in + jit-recording.cc. */ + +ssize_t +gcc_jit_type_get_size (gcc_jit_type *type) +{ + RETURN_VAL_IF_FAIL (type, -1, NULL, NULL, "NULL type"); + RETURN_VAL_IF_FAIL (type->is_int (), -1, NULL, NULL, "only getting the size of an int type is supported for now"); + return type->get_size (); +} + /* Public entrypoint. See description in libgccjit.h. After error-checking, the real work is done by the @@ -2119,7 +2135,7 @@ gcc_jit_context_new_binary_op (gcc_jit_context *ctxt, RETURN_NULL_IF_FAIL (a, ctxt, loc, "NULL a"); RETURN_NULL_IF_FAIL (b, ctxt, loc, "NULL b"); RETURN_NULL_IF_FAIL_PRINTF4 ( - a->get_type ()->unqualified () == b->get_type ()->unqualified (), + gcc_jit_compatible_types ((gcc_jit_type*)a->get_type ()->unqualified (), (gcc_jit_type*)b->get_type ()->unqualified ()), ctxt, loc, "mismatching types for binary op:" " a: %s (type: %s) b: %s (type: %s)", @@ -2228,8 +2244,8 @@ gcc_jit_context_new_call (gcc_jit_context *ctxt, param->get_type ()->get_debug_string ()); RETURN_NULL_IF_FAIL_PRINTF6 ( - compatible_types (param->get_type (), - arg->get_type ()), + gcc_jit_compatible_types ((gcc_jit_type*) param->get_type (), + (gcc_jit_type*) arg->get_type ()), ctxt, loc, "mismatching types for argument %d of function \"%s\":" " assignment to param %s (type: %s) from %s (type: %s)", @@ -2317,8 +2333,8 @@ gcc_jit_context_new_call_through_ptr (gcc_jit_context *ctxt, param_type->get_debug_string ()); RETURN_NULL_IF_FAIL_PRINTF6 ( - compatible_types (param_type, - arg->get_type ()), + gcc_jit_compatible_types ((gcc_jit_type*) param_type, + (gcc_jit_type*) arg->get_type ()), ctxt, loc, "mismatching types for argument %d of fn_ptr: %s:" " assignment to param %d (type: %s) from %s (type: %s)", @@ -2729,8 +2745,8 @@ gcc_jit_block_add_assignment (gcc_jit_block *block, RETURN_IF_FAIL (lvalue, ctxt, loc, "NULL lvalue"); RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue"); RETURN_IF_FAIL_PRINTF4 ( - compatible_types (lvalue->get_type (), - rvalue->get_type ()), + gcc_jit_compatible_types ((gcc_jit_type*) lvalue->get_type (), + (gcc_jit_type*) rvalue->get_type ()), ctxt, loc, "mismatching types:" " assignment to %s (type: %s) from %s (type: %s)", @@ -2775,8 +2791,8 @@ gcc_jit_block_add_assignment_op (gcc_jit_block *block, op); RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue"); RETURN_IF_FAIL_PRINTF4 ( - compatible_types (lvalue->get_type (), - rvalue->get_type ()), + gcc_jit_compatible_types ((gcc_jit_type*) lvalue->get_type (), + (gcc_jit_type*) rvalue->get_type ()), ctxt, loc, "mismatching types:" " assignment to %s (type: %s) involving %s (type: %s)", @@ -2932,9 +2948,9 @@ gcc_jit_block_end_with_return (gcc_jit_block *block, gcc::jit::recording::function *func = block->get_function (); RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue"); RETURN_IF_FAIL_PRINTF4 ( - compatible_types ( - func->get_return_type (), - rvalue->get_type ()), + gcc_jit_compatible_types ( + (gcc_jit_type*) func->get_return_type (), + (gcc_jit_type*) rvalue->get_type ()), ctxt, loc, "mismatching types:" " return of %s (type: %s) in function %s (return type: %s)", @@ -3932,8 +3948,8 @@ gcc_jit_context_new_rvalue_from_vector (gcc_jit_context *ctxt, RETURN_NULL_IF_FAIL_PRINTF1 ( elements[i], ctxt, loc, "NULL elements[%zi]", i); RETURN_NULL_IF_FAIL_PRINTF4 ( - compatible_types (element_type, - elements[i]->get_type ()), + gcc_jit_compatible_types ((gcc_jit_type*) element_type, + (gcc_jit_type*) elements[i]->get_type ()), ctxt, loc, "mismatching type for element[%zi] (expected type: %s): %s (type: %s)", i, diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h index 2a5ffacb1fe..1d9da354f31 100644 --- a/gcc/jit/libgccjit.h +++ b/gcc/jit/libgccjit.h @@ -574,8 +574,19 @@ enum gcc_jit_types /* Complex numbers. */ GCC_JIT_TYPE_COMPLEX_FLOAT, GCC_JIT_TYPE_COMPLEX_DOUBLE, - GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE - + GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE, + + /* Sized integer types. */ + GCC_JIT_TYPE_UINT8_T, + GCC_JIT_TYPE_UINT16_T, + GCC_JIT_TYPE_UINT32_T, + GCC_JIT_TYPE_UINT64_T, + GCC_JIT_TYPE_UINT128_T, + GCC_JIT_TYPE_INT8_T, + GCC_JIT_TYPE_INT16_T, + GCC_JIT_TYPE_INT32_T, + GCC_JIT_TYPE_INT64_T, + GCC_JIT_TYPE_INT128_T }; extern gcc_jit_type * @@ -601,6 +612,23 @@ gcc_jit_type_get_const (gcc_jit_type *type); extern gcc_jit_type * gcc_jit_type_get_volatile (gcc_jit_type *type); +#define LIBGCCJIT_HAVE_SIZED_INTEGERS + +/* Given types LTYPE and RTYPE, return non-zero if they are compatible. + This API entrypoint was added in LIBGCCJIT_ABI_20; you can test for its + presence using + #ifdef LIBGCCJIT_HAVE_SIZED_INTEGERS */ +extern int +gcc_jit_compatible_types (gcc_jit_type *ltype, + gcc_jit_type *rtype); + +/* Given type "T", get its size. + This API entrypoint was added in LIBGCCJIT_ABI_20; you can test for its + presence using + #ifdef LIBGCCJIT_HAVE_SIZED_INTEGERS */ +extern ssize_t +gcc_jit_type_get_size (gcc_jit_type *type); + /* Given type "T", get type "T[N]" (for a constant N). */ extern gcc_jit_type * gcc_jit_context_new_array_type (gcc_jit_context *ctxt, diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map index f373fd39ac7..1c002786e84 100644 --- a/gcc/jit/libgccjit.map +++ b/gcc/jit/libgccjit.map @@ -243,3 +243,9 @@ LIBGCCJIT_ABI_19 { gcc_jit_context_new_union_constructor; gcc_jit_global_set_initializer_rvalue; } LIBGCCJIT_ABI_18; + +LIBGCCJIT_ABI_20 { + global: + gcc_jit_compatible_types; + gcc_jit_type_get_size; +} LIBGCCJIT_ABI_19; diff --git a/gcc/testsuite/jit.dg/test-types.c b/gcc/testsuite/jit.dg/test-types.c index 8debcd7eb82..6836597d14e 100644 --- a/gcc/testsuite/jit.dg/test-types.c +++ b/gcc/testsuite/jit.dg/test-types.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -29,6 +30,21 @@ struct zoo long long m_long_long; unsigned long long m_unsigned_long_long; + uint8_t m_u8; + uint16_t m_u16; + uint32_t m_u32; + uint64_t m_u64; + + int8_t m_i8; + int16_t m_i16; + int32_t m_i32; + int64_t m_i64; + +#ifdef __SIZEOF_INT128__ + __uint128_t m_u128; + __int128_t m_i128; +#endif + int m_sized_int_type; float m_float; @@ -101,6 +117,31 @@ 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"); + gcc_jit_field *field_m_u8 = + CREATE_FIELD (GCC_JIT_TYPE_UINT8_T, "m_u8"); + gcc_jit_field *field_m_u16 = + CREATE_FIELD (GCC_JIT_TYPE_UINT16_T, "m_u16"); + gcc_jit_field *field_m_u32 = + CREATE_FIELD (GCC_JIT_TYPE_UINT32_T, "m_u32"); + gcc_jit_field *field_m_u64 = + CREATE_FIELD (GCC_JIT_TYPE_UINT64_T, "m_u64"); + + gcc_jit_field *field_m_i8 = + CREATE_FIELD (GCC_JIT_TYPE_INT8_T, "m_i8"); + gcc_jit_field *field_m_i16 = + CREATE_FIELD (GCC_JIT_TYPE_INT16_T, "m_i16"); + gcc_jit_field *field_m_i32 = + CREATE_FIELD (GCC_JIT_TYPE_INT32_T, "m_i32"); + gcc_jit_field *field_m_i64 = + CREATE_FIELD (GCC_JIT_TYPE_INT64_T, "m_i64"); + +#ifdef __SIZEOF_INT128__ + gcc_jit_field *field_m_u128 = + CREATE_FIELD (GCC_JIT_TYPE_UINT128_T, "m_u128"); + gcc_jit_field *field_m_i128 = + CREATE_FIELD (GCC_JIT_TYPE_INT128_T, "m_i128"); +#endif + /* Signed int type with sizeof (int): */ gcc_jit_type *sized_int_type = gcc_jit_context_get_int_type (ctxt, sizeof (int), 1); @@ -147,6 +188,21 @@ create_code (gcc_jit_context *ctxt, void *user_data) field_m_long_long, field_m_unsigned_long_long, + field_m_u8, + field_m_u16, + field_m_u32, + field_m_u64, + + field_m_i8, + field_m_i16, + field_m_i32, + field_m_i64, + +#ifdef __SIZEOF_INT128__ + field_m_u128, + field_m_i128, +#endif + field_m_sized_int_type, field_m_float, @@ -266,6 +322,61 @@ 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_u8, + gcc_jit_context_new_rvalue_from_int ( + ctxt, + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UINT8_T), + 123)) + ASSIGN(field_m_u16, + gcc_jit_context_new_rvalue_from_int ( + ctxt, + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UINT16_T), + 12345)) + ASSIGN(field_m_u32, + gcc_jit_context_new_rvalue_from_int ( + ctxt, + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UINT32_T), + 123456789)) + ASSIGN(field_m_u64, + gcc_jit_context_new_rvalue_from_int ( + ctxt, + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UINT64_T), + 123456789)) + + ASSIGN(field_m_i8, + gcc_jit_context_new_rvalue_from_int ( + ctxt, + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT8_T), + -1)) + ASSIGN(field_m_i16, + gcc_jit_context_new_rvalue_from_int ( + ctxt, + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT16_T), + -2)) + ASSIGN(field_m_i32, + gcc_jit_context_new_rvalue_from_int ( + ctxt, + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT32_T), + -3)) + ASSIGN(field_m_i64, + gcc_jit_context_new_rvalue_from_int ( + ctxt, + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT64_T), + -4)) + +#ifdef __SIZEOF_INT128__ + ASSIGN(field_m_u128, + gcc_jit_context_new_rvalue_from_int ( + ctxt, + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UINT128_T), + 123456789)) + ASSIGN(field_m_i128, + gcc_jit_context_new_rvalue_from_int ( + ctxt, + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT128_T), + -5)) +#endif + ASSIGN(field_m_sized_int_type, gcc_jit_context_new_rvalue_from_int ( ctxt, @@ -347,6 +458,21 @@ 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_u8, 123); + CHECK_VALUE (z.m_u16, 12345); + CHECK_VALUE (z.m_u32, 123456789); + CHECK_VALUE (z.m_u64, 123456789); + + CHECK_VALUE (z.m_i8, -1); + CHECK_VALUE (z.m_i16, -2); + CHECK_VALUE (z.m_i32, -3); + CHECK_VALUE (z.m_i64, -4); + +#ifdef __SIZEOF_INT128__ + CHECK_VALUE (z.m_u128, 123456789); + CHECK_VALUE (z.m_i128, -5); +#endif + CHECK_VALUE (z.m_sized_int_type, 500); CHECK_VALUE (z.m_float, 3.141f); @@ -358,4 +484,9 @@ verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) CHECK_VALUE (z.m_size_t, sizeof (struct zoo)); CHECK_VALUE (z.m_FILE_ptr, stderr); + + if (sizeof(long) == 8) + CHECK (gcc_jit_compatible_types ( + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_LONG), + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT64_T))); } -- 2.26.2.7.g19db9cfb68.dirty