Index: gcc/jit/jit-playback.c =================================================================== --- gcc/jit/jit-playback.c (revision 225860) +++ gcc/jit/jit-playback.c (working copy) @@ -1,4 +1,5 @@ -/* Internals of libgccjit: classes for playing back recorded API calls. +/* This jit-playback.c file is in -*- C++ -*- ... + Internals of libgccjit: classes for playing back recorded API calls. Copyright (C) 2013-2015 Free Software Foundation, Inc. Contributed by David Malcolm . @@ -573,6 +574,30 @@ new_rvalue_from_const (type *type, } } + +/* Specialization of making an rvalue from a const, for host . */ + +template <> +rvalue * +context:: +new_rvalue_from_const (type *type, + long long value) +{ + // FIXME: type-checking, or coercion? + tree inner_type = type->as_tree (); + if (INTEGRAL_TYPE_P (inner_type)) + { + tree inner = build_int_cst (inner_type, value); + return new rvalue (this, inner); + } + else + { + REAL_VALUE_TYPE real_value; + real_from_integer (&real_value, VOIDmode, value, SIGNED); + tree inner = build_real (inner_type, real_value); + return new rvalue (this, inner); + } +} /* Specialization of making an rvalue from a const, for host . */ template <> Index: gcc/jit/jit-recording.c =================================================================== --- gcc/jit/jit-recording.c (revision 225860) +++ gcc/jit/jit-recording.c (working copy) @@ -1,4 +1,5 @@ -/* Internals of libgccjit: classes for recording calls made to the JIT API. +/* This jit-recording.c file is in -*- C++ -*- ... + Internals of libgccjit: classes for recording calls made to the JIT API. Copyright (C) 2013-2015 Free Software Foundation, Inc. Contributed by David Malcolm . @@ -4072,6 +4073,7 @@ recording::global::write_reproducer (reproducer &r /* Explicit specialization of the various mementos we're interested in. */ template class recording::memento_of_new_rvalue_from_const ; template class recording::memento_of_new_rvalue_from_const ; +template class recording::memento_of_new_rvalue_from_const ; template class recording::memento_of_new_rvalue_from_const ; template class recording::memento_of_new_rvalue_from_const ; @@ -4161,6 +4163,22 @@ memento_of_new_rvalue_from_const ::make_debu m_value); } + +/* The make_debug_string specialization for , rendering it as + (TARGET_TYPE)LITERAL + e.g. + "(long long)42". */ + +template <> +string * +memento_of_new_rvalue_from_const ::make_debug_string () +{ + return string::from_printf (m_ctxt, + "(%s)%lli", + m_type->get_debug_string (), + m_value); +} + /* The get_wide_int specialization for . */ template <> @@ -4171,6 +4189,16 @@ memento_of_new_rvalue_from_const ::get_wide_ return true; } +/* The get_wide_int specialization for . */ + +template <> +bool +memento_of_new_rvalue_from_const ::get_wide_int (wide_int *out) const +{ + *out = wi::shwi (m_value, sizeof (m_value) * 8); + return true; +} + /* The write_reproducer specialization for . */ template <> @@ -4209,6 +4237,43 @@ recording::memento_of_new_rvalue_from_const m_value); } + +/* The write_reproducer specialization for . */ + +template <> +void +recording::memento_of_new_rvalue_from_const ::write_reproducer (reproducer &r) +{ + const char *id = r.make_identifier (this, "rvalue"); + + /* We have to special-case LONG_LONG_MIN like in the previous specialization + and hence we'd get: + error: integer constant is so large that it is unsigned [-Werror] + Workaround this by writing (LONG_LONG_MIN + 1) - 1. */ + if (m_value == LONG_LONG_MIN) + { + r.write (" gcc_jit_rvalue *%s =\n" + " gcc_jit_context_new_rvalue_from_long_long (%s, /* gcc_jit_context *ctxt */\n" + " %s, /* gcc_jit_type *numeric_type */\n" + " %lldLL - 1); /* long long value */\n", + id, + r.get_identifier (get_context ()), + r.get_identifier_as_type (m_type), + m_value + 1);; + return; + } + + r.write (" gcc_jit_rvalue *%s =\n" + " gcc_jit_context_new_rvalue_from_long_long (%s, /* gcc_jit_context *ctxt */\n" + " %s, /* gcc_jit_type *numeric_type */\n" + " %lldLL); /* long long value */\n", + id, + r.get_identifier (get_context ()), + r.get_identifier_as_type (m_type), + m_value); + } + + /* The make_debug_string specialization for , rendering it as (TARGET_TYPE)LITERAL e.g. Index: gcc/jit/libgccjit.c =================================================================== --- gcc/jit/libgccjit.c (revision 225860) +++ gcc/jit/libgccjit.c (working copy) @@ -1,4 +1,5 @@ -/* Implementation of the C API; all wrappers into the internal C++ API +/* This libgccjit.c file is in -*- C++ -*- ... + Implementation of the C API; all wrappers into the internal C++ API Copyright (C) 2013-2015 Free Software Foundation, Inc. Contributed by David Malcolm . @@ -1154,6 +1155,77 @@ gcc_jit_context_new_rvalue_from_long (gcc_jit_cont ->new_rvalue_from_const (numeric_type, value)); } +/* Public entrypoint. See description in libgccjit.h. */ + +gcc_jit_rvalue * +gcc_jit_context_new_rvalue_from_long_long (gcc_jit_context *ctxt, + gcc_jit_type *numeric_type, + long long value) +{ + RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context"); + JIT_LOG_FUNC (ctxt->get_logger ()); + RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type); + + return ((gcc_jit_rvalue *)ctxt + ->new_rvalue_from_const (numeric_type, value)); +} + + +/* Public entrypoint. See description in libgccjit.h. */ + +gcc_jit_rvalue * +gcc_jit_context_new_rvalue_from_int32 (gcc_jit_context *ctxt, + gcc_jit_type *numeric_type, + int32_t value) +{ + RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context"); + JIT_LOG_FUNC (ctxt->get_logger ()); + RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type); + + return ((gcc_jit_rvalue *)ctxt + ->new_rvalue_from_const (numeric_type, (long) value)); +} + + +/* Public entrypoint. See description in libgccjit.h. */ + +gcc_jit_rvalue * +gcc_jit_context_new_rvalue_from_int64 (gcc_jit_context *ctxt, + gcc_jit_type *numeric_type, + int64_t value) +{ + RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context"); + JIT_LOG_FUNC (ctxt->get_logger ()); + RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type); + + return ((gcc_jit_rvalue *)ctxt + ->new_rvalue_from_const (numeric_type, (long long) value)); +} + + +/* Public entrypoint. See description in libgccjit.h. */ + +gcc_jit_rvalue * +gcc_jit_context_new_rvalue_from_intptr (gcc_jit_context *ctxt, + gcc_jit_type *numeric_type, + intptr_t value) +{ + RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context"); + JIT_LOG_FUNC (ctxt->get_logger ()); + RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type); + + if (sizeof(intptr_t) == sizeof(int)) + return ((gcc_jit_rvalue *)ctxt + ->new_rvalue_from_const (numeric_type, (int) value)); + else if (sizeof(intptr_t) == sizeof(long)) + return ((gcc_jit_rvalue *)ctxt + ->new_rvalue_from_const (numeric_type, (long) value)); + else + return ((gcc_jit_rvalue *)ctxt + ->new_rvalue_from_const (numeric_type, (long long) value)); +} + + /* Public entrypoint. See description in libgccjit.h. This is essentially equivalent to: Index: gcc/jit/libgccjit.h =================================================================== --- gcc/jit/libgccjit.h (revision 225860) +++ gcc/jit/libgccjit.h (working copy) @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see #define LIBGCCJIT_H #include +#include #ifdef __cplusplus extern "C" { @@ -752,6 +753,32 @@ gcc_jit_context_new_rvalue_from_long (gcc_jit_cont long value); extern gcc_jit_rvalue * +gcc_jit_context_new_rvalue_from_long_long (gcc_jit_context *ctxt, + gcc_jit_type *numeric_type, + long long value); + +/* Internally same as gcc_jit_context_new_rvalue_from_long, but takes + an int32_t for convenience. */ +extern gcc_jit_rvalue * +gcc_jit_context_new_rvalue_from_int32 (gcc_jit_context *ctxt, + gcc_jit_type *numeric_type, + int32_t value); + +/* Internally same as gcc_jit_context_new_rvalue_from_long_long, but + takes an int64_t for convenience. */ +extern gcc_jit_rvalue * +gcc_jit_context_new_rvalue_from_int64 (gcc_jit_context *ctxt, + gcc_jit_type *numeric_type, + int64_t value); + +/* Internally same as gcc_jit_context_new_rvalue_from_long_long, but + takes an intptr_t for convenience. */ +extern gcc_jit_rvalue * +gcc_jit_context_new_rvalue_from_intptr (gcc_jit_context *ctxt, + gcc_jit_type *numeric_type, + intptr_t value); + +extern gcc_jit_rvalue * gcc_jit_context_zero (gcc_jit_context *ctxt, gcc_jit_type *numeric_type); Index: gcc/jit/libgccjit.map =================================================================== --- gcc/jit/libgccjit.map (revision 225860) +++ gcc/jit/libgccjit.map (working copy) @@ -128,3 +128,12 @@ LIBGCCJIT_ABI_3 { gcc_jit_case_as_object; gcc_jit_context_new_case; } LIBGCCJIT_ABI_2; + +# Add support for long long & int32 & int64 & intptr +LIBGCCJIT_ABI_4 { + global: + gcc_jit_context_new_rvalue_from_int32; + gcc_jit_context_new_rvalue_from_int64; + gcc_jit_context_new_rvalue_from_intptr; + gcc_jit_context_new_rvalue_from_long_long; +} LIBGCCJIT_ABI_3; \ No newline at end of file Index: gcc/testsuite/jit.dg/test-constants.c =================================================================== --- gcc/testsuite/jit.dg/test-constants.c (revision 225860) +++ gcc/testsuite/jit.dg/test-constants.c (working copy) @@ -173,6 +173,79 @@ verify_long_constants (gcc_jit_result *result) } /********************************************************************** + Tests of gcc_jit_context_new_rvalue_from_long_long. + **********************************************************************/ + +static const char * +make_test_of_long_long_constant (gcc_jit_context *ctxt, + gcc_jit_type *type, + long long value, + const char *funcname) +{ + /* Make a test function of the form: + long long funcname (void) + { + return VALUE; + } + and return a debug dump of VALUE so that + the caller can sanity-check the debug dump implementation. + */ + gcc_jit_rvalue *rvalue = + gcc_jit_context_new_rvalue_from_long_long (ctxt, type, value); + make_test_of_constant (ctxt, type, rvalue, funcname); + return gcc_jit_object_get_debug_string ( + gcc_jit_rvalue_as_object (rvalue)); +} + +static void +make_tests_of_long_long_constants (gcc_jit_context *ctxt) +{ + gcc_jit_type *long_long_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_LONG_LONG); + + CHECK_STRING_VALUE + ( + make_test_of_long_long_constant (ctxt, + long_long_type, + 0, + "test_long_long_constant_0"), + "(long long)0"); + make_test_of_long_long_constant (ctxt, + long_long_type, + LLONG_MAX, + "test_long_long_constant_LLONG_MAX"); + make_test_of_long_long_constant (ctxt, + long_long_type, + LLONG_MIN, + "test_long_long_constant_LLONG_MIN"); +} + +static void +verify_long_long_constants (gcc_jit_result *result) +{ + typedef long long (*test_fn) (void); + + test_fn test_long_long_constant_0 = + (test_fn)gcc_jit_result_get_code (result, + "test_long_long_constant_0"); + CHECK_NON_NULL (test_long_long_constant_0); + CHECK_VALUE (test_long_long_constant_0 (), 0); + + test_fn test_long_long_constant_LLONG_MAX = + (test_fn)gcc_jit_result_get_code (result, + "test_long_long_constant_LLONG_MAX"); + CHECK_NON_NULL (test_long_long_constant_LLONG_MAX); + CHECK_VALUE (test_long_long_constant_LLONG_MAX (), LLONG_MAX); + + test_fn test_long_long_constant_LLONG_MIN = + (test_fn)gcc_jit_result_get_code (result, + "test_long_long_constant_LLONG_MIN"); + CHECK_NON_NULL (test_long_long_constant_LLONG_MIN); + CHECK_VALUE (test_long_long_constant_LLONG_MIN (), LLONG_MIN); +} + + +/********************************************************************** Tests of gcc_jit_context_new_rvalue_from_double. **********************************************************************/ @@ -323,6 +396,7 @@ create_code (gcc_jit_context *ctxt, void *user_dat { make_tests_of_int_constants (ctxt); make_tests_of_long_constants (ctxt); + make_tests_of_long_long_constants (ctxt); make_tests_of_double_constants (ctxt); make_tests_of_ptr_constants (ctxt); } @@ -334,6 +408,7 @@ verify_code (gcc_jit_context *ctxt, gcc_jit_result verify_int_constants (result); verify_long_constants (result); + verify_long_long_constants (result); verify_double_constants (result); verify_ptr_constants (result); }