jit_target_add_supported_target_dependent_type (GCC_JIT_TYPE_INT128_T);
}
+ if (float16_type_node != NULL && TYPE_PRECISION (float16_type_node) == 16)
+ jit_target_add_supported_target_dependent_type (GCC_JIT_TYPE_FLOAT16);
+
+ if (float32_type_node != NULL && TYPE_PRECISION (float32_type_node) == 32)
+ jit_target_add_supported_target_dependent_type (GCC_JIT_TYPE_FLOAT32);
+
+ if (float64_type_node != NULL && TYPE_PRECISION (float64_type_node) == 64)
+ jit_target_add_supported_target_dependent_type (GCC_JIT_TYPE_FLOAT64);
+
+ if (float128_type_node != NULL && TYPE_PRECISION (float128_type_node) == 128)
+ jit_target_add_supported_target_dependent_type (GCC_JIT_TYPE_FLOAT128);
+
#define ADD_TARGET_INFO jit_add_target_info
#include "i386-rust-and-jit.inc"
#undef ADD_TARGET_INFO
-
* - :c:data:`GCC_JIT_TYPE_LONG_DOUBLE`
-
+ * - :c:data:`GCC_JIT_TYPE_FLOAT16`
+ -
+ * - :c:data:`GCC_JIT_TYPE_FLOAT32`
+ -
+ * - :c:data:`GCC_JIT_TYPE_FLOAT64`
+ -
+ * - :c:data:`GCC_JIT_TYPE_FLOAT128`
+ -
* - :c:data:`GCC_JIT_TYPE_CONST_CHAR_PTR`
- C type: ``(const char *)``
* - :c:data:`GCC_JIT_TYPE_SIZE_T`
// FIXME: wrong type.
return new recording::memento_of_get_type (&target_builtins_ctxt,
GCC_JIT_TYPE_VOID);
- /* TODO: Remove when we add support for sized floating-point types. */
- for (int i = 0; i < NUM_FLOATN_NX_TYPES; i++)
- if (type == FLOATN_NX_TYPE_NODE (i))
- // FIXME: wrong type.
- return new recording::memento_of_get_type (&target_builtins_ctxt,
- GCC_JIT_TYPE_VOID);
if (type == void_type_node)
return new recording::memento_of_get_type (&target_builtins_ctxt,
GCC_JIT_TYPE_VOID);
else if (type == bfloat16_type_node)
return new recording::memento_of_get_type (&target_builtins_ctxt,
GCC_JIT_TYPE_BFLOAT16);
+ else if (type == float16_type_node)
+ {
+ return new recording::memento_of_get_type (&target_builtins_ctxt,
+ GCC_JIT_TYPE_FLOAT16);
+ }
+ else if (type == float32_type_node)
+ {
+ return new recording::memento_of_get_type (&target_builtins_ctxt,
+ GCC_JIT_TYPE_FLOAT32);
+ }
+ else if (type == float64_type_node)
+ {
+ return new recording::memento_of_get_type (&target_builtins_ctxt,
+ GCC_JIT_TYPE_FLOAT64);
+ }
+ else if (type == float128_type_node)
+ {
+ return new recording::memento_of_get_type (&target_builtins_ctxt,
+ GCC_JIT_TYPE_FLOAT128);
+ }
else if (type == dfloat128_type_node)
// FIXME: wrong type.
return new recording::memento_of_get_type (&target_builtins_ctxt,
#endif
#endif
-const int NUM_GCC_JIT_TYPES = GCC_JIT_TYPE_BFLOAT16 + 1;
+const int NUM_GCC_JIT_TYPES = GCC_JIT_TYPE_FLOAT128 + 1;
/* This comment is included by the docs.
return double_type_node;
case GCC_JIT_TYPE_LONG_DOUBLE:
return long_double_type_node;
+ case GCC_JIT_TYPE_FLOAT16:
+ if (float16_type_node == NULL || TYPE_PRECISION (float16_type_node) != 16)
+ {
+ add_error (NULL, "gcc_jit_types value unsupported on this target: %i",
+ type_);
+ return NULL;
+ }
+ return float16_type_node;
+ case GCC_JIT_TYPE_FLOAT32:
+ if (float32_type_node == NULL || TYPE_PRECISION (float32_type_node) != 32)
+ {
+ add_error (NULL, "gcc_jit_types value unsupported on this target: %i",
+ type_);
+ return NULL;
+ }
+ return float32_type_node;
+ case GCC_JIT_TYPE_FLOAT64:
+ if (float64_type_node == NULL || TYPE_PRECISION (float64_type_node) != 64)
+ {
+ add_error (NULL, "gcc_jit_types value unsupported on this target: %i",
+ type_);
+ return NULL;
+ }
+ return float64_type_node;
+ case GCC_JIT_TYPE_FLOAT128:
+ if (float128_type_node == NULL
+ || TYPE_PRECISION (float128_type_node) != 128)
+ {
+ add_error (NULL, "gcc_jit_types value unsupported on this target: %i",
+ type_);
+ return NULL;
+ }
+ return float128_type_node;
case GCC_JIT_TYPE_SIZE_T:
return size_type_node;
m = targetm.c.mode_for_floating_type (TI_LONG_DOUBLE_TYPE);
size = GET_MODE_PRECISION (m).to_constant ();
break;
+ case GCC_JIT_TYPE_FLOAT16:
+ size = 16;
+ break;
+ case GCC_JIT_TYPE_FLOAT32:
+ size = 32;
+ break;
+ case GCC_JIT_TYPE_FLOAT64:
+ size = 64;
+ break;
+ case GCC_JIT_TYPE_FLOAT128:
+ size = 128;
+ break;
case GCC_JIT_TYPE_SIZE_T:
size = MAX_BITS_PER_WORD;
break;
case GCC_JIT_TYPE_BFLOAT16:
case GCC_JIT_TYPE_DOUBLE:
case GCC_JIT_TYPE_LONG_DOUBLE:
+ case GCC_JIT_TYPE_FLOAT16:
+ case GCC_JIT_TYPE_FLOAT32:
+ case GCC_JIT_TYPE_FLOAT64:
+ case GCC_JIT_TYPE_FLOAT128:
case GCC_JIT_TYPE_COMPLEX_FLOAT:
case GCC_JIT_TYPE_COMPLEX_DOUBLE:
case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
case GCC_JIT_TYPE_BFLOAT16:
case GCC_JIT_TYPE_DOUBLE:
case GCC_JIT_TYPE_LONG_DOUBLE:
+ case GCC_JIT_TYPE_FLOAT16:
+ case GCC_JIT_TYPE_FLOAT32:
+ case GCC_JIT_TYPE_FLOAT64:
+ case GCC_JIT_TYPE_FLOAT128:
return false;
case GCC_JIT_TYPE_CONST_CHAR_PTR:
case GCC_JIT_TYPE_BFLOAT16:
case GCC_JIT_TYPE_DOUBLE:
case GCC_JIT_TYPE_LONG_DOUBLE:
+ case GCC_JIT_TYPE_FLOAT16:
+ case GCC_JIT_TYPE_FLOAT32:
+ case GCC_JIT_TYPE_FLOAT64:
+ case GCC_JIT_TYPE_FLOAT128:
case GCC_JIT_TYPE_CONST_CHAR_PTR:
case GCC_JIT_TYPE_BFLOAT16:
case GCC_JIT_TYPE_DOUBLE:
case GCC_JIT_TYPE_LONG_DOUBLE:
+ case GCC_JIT_TYPE_FLOAT16:
+ case GCC_JIT_TYPE_FLOAT32:
+ case GCC_JIT_TYPE_FLOAT64:
+ case GCC_JIT_TYPE_FLOAT128:
return true;
case GCC_JIT_TYPE_CONST_CHAR_PTR:
case GCC_JIT_TYPE_BFLOAT16:
case GCC_JIT_TYPE_DOUBLE:
case GCC_JIT_TYPE_LONG_DOUBLE:
+ case GCC_JIT_TYPE_FLOAT16:
+ case GCC_JIT_TYPE_FLOAT32:
+ case GCC_JIT_TYPE_FLOAT64:
+ case GCC_JIT_TYPE_FLOAT128:
return false;
case GCC_JIT_TYPE_CONST_CHAR_PTR:
"__int32_t", /* GCC_JIT_TYPE_INT32_T */
"__int64_t", /* GCC_JIT_TYPE_INT64_T */
"__int128_t", /* GCC_JIT_TYPE_INT128_T */
-
- "bfloat16", /* GCC_JIT_TYPE_BFLOAT16 */
+ "bfloat16", /* GCC_JIT_TYPE_BFLOAT16 */
+ "_Float16", /* GCC_JIT_TYPE_FLOAT16 */
+ "_Float32", /* GCC_JIT_TYPE_FLOAT32 */
+ "_Float64", /* GCC_JIT_TYPE_FLOAT64 */
+ "__float128", /* GCC_JIT_TYPE_FLOAT128 */
};
/* Implementation of recording::memento::make_debug_string for
"GCC_JIT_TYPE_INT64_T",
"GCC_JIT_TYPE_INT128_T",
"GCC_JIT_TYPE_BFLOAT16",
+ "GCC_JIT_TYPE_FLOAT16",
+ "GCC_JIT_TYPE_FLOAT32",
+ "GCC_JIT_TYPE_FLOAT64",
+ "GCC_JIT_TYPE_FLOAT128",
};
void
GCC_JIT_TYPE_INT128_T,
GCC_JIT_TYPE_BFLOAT16,
+ GCC_JIT_TYPE_FLOAT16,
+ GCC_JIT_TYPE_FLOAT32,
+ GCC_JIT_TYPE_FLOAT64,
+ GCC_JIT_TYPE_FLOAT128,
};
extern gcc_jit_type *
#undef create_code
#undef verify_code
+/* test-sized-float.c */
+#define create_code create_code_sized_float
+#define verify_code verify_code_sized_float
+#include "test-sized-float.c"
+#undef create_code
+#undef verify_code
+
/* test-target-builtins.c: This can't be in the testcases array as it
is target-specific. */
{"sizeof",
create_code_sizeof,
verify_code_sizeof},
+ {"sized-float",
+ create_code_sized_float,
+ verify_code_sized_float},
{"string_literal",
create_code_string_literal,
verify_code_string_literal},
--- /dev/null
+#include <stdio.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+struct float_zoo
+{
+ _Float16 m_float16;
+ _Float32 m_float32;
+ _Float64 m_float64;
+ __float128 m_float128;
+};
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+
+ void
+ test_caller (struct float_zoo *z)
+ {
+ for each fields "m_field":
+ z->m_field = ...some data;
+ }
+ */
+ gcc_jit_type *void_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
+
+#define CREATE_FIELD(TYPE, NAME) \
+ gcc_jit_context_new_field ( \
+ ctxt, NULL, \
+ gcc_jit_context_get_type (ctxt, TYPE), \
+ NAME)
+
+ gcc_jit_context *info_ctxt = gcc_jit_context_acquire ();
+ gcc_jit_target_info *target_info = gcc_jit_context_get_target_info (info_ctxt);
+
+ enum gcc_jit_types float_type1 = GCC_JIT_TYPE_FLOAT;
+ if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT16))
+ float_type1 = GCC_JIT_TYPE_FLOAT16;
+
+ enum gcc_jit_types float_type2 = GCC_JIT_TYPE_FLOAT;
+ if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT32))
+ float_type2 = GCC_JIT_TYPE_FLOAT32;
+
+ enum gcc_jit_types float_type3 = GCC_JIT_TYPE_FLOAT;
+ if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT64))
+ float_type3 = GCC_JIT_TYPE_FLOAT64;
+
+ enum gcc_jit_types float_type4 = GCC_JIT_TYPE_FLOAT;
+ if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT128))
+ float_type4 = GCC_JIT_TYPE_FLOAT128;
+
+ gcc_jit_field *field_m_float16 = CREATE_FIELD(float_type1, "m_float16");
+ gcc_jit_field *field_m_float32 = CREATE_FIELD(float_type2, "m_float32");
+ gcc_jit_field *field_m_float64 = CREATE_FIELD(float_type3, "m_float64");
+ gcc_jit_field *field_m_float128 = CREATE_FIELD(float_type4, "m_float128");
+
+#undef CREATE_FIELD
+
+ gcc_jit_field *zoo_fields[] = {
+ field_m_float16,
+ field_m_float32,
+ field_m_float64,
+ field_m_float128,
+ };
+
+ gcc_jit_type *zoo_type =
+ gcc_jit_struct_as_type (
+ gcc_jit_context_new_struct_type (
+ ctxt,
+ NULL,
+ "float_zoo",
+ sizeof (zoo_fields) / sizeof (zoo_fields[0]),
+ zoo_fields));
+
+ gcc_jit_type *zoo_ptr_type =
+ gcc_jit_type_get_pointer (zoo_type);
+
+ /* Build the test_fn. */
+ gcc_jit_param *param_z =
+ gcc_jit_context_new_param (ctxt, NULL, zoo_ptr_type, "z");
+ gcc_jit_function *test_fn =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ void_type,
+ "test_float_types",
+ 1, ¶m_z,
+ 0);
+ gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
+
+ /* Write to the various fields of param "z". */
+#define ASSIGN(FIELD, EXPR) \
+ gcc_jit_block_add_assignment ( \
+ block, NULL, \
+ gcc_jit_rvalue_dereference_field ( \
+ gcc_jit_param_as_rvalue (param_z), \
+ NULL, \
+ (FIELD)), \
+ (EXPR));
+
+ ASSIGN(field_m_float16,
+ gcc_jit_context_new_rvalue_from_double (
+ ctxt,
+ gcc_jit_context_get_type (ctxt, float_type1),
+ 3.141))
+ ASSIGN(field_m_float32,
+ gcc_jit_context_new_rvalue_from_double (
+ ctxt,
+ gcc_jit_context_get_type (ctxt, float_type2),
+ 3.141))
+ ASSIGN(field_m_float64,
+ gcc_jit_context_new_rvalue_from_double (
+ ctxt,
+ gcc_jit_context_get_type (ctxt, float_type3),
+ 3.141))
+ ASSIGN(field_m_float128,
+ gcc_jit_context_new_rvalue_from_double (
+ ctxt,
+ gcc_jit_context_get_type (ctxt, float_type4),
+ 3.141))
+
+#undef ASSIGN
+
+ gcc_jit_block_end_with_void_return (block, NULL);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ typedef void (*fn_type) (struct float_zoo *);
+ CHECK_NON_NULL (result);
+
+ fn_type test_float_types =
+ (fn_type)gcc_jit_result_get_code (result, "test_float_types");
+ CHECK_NON_NULL (test_float_types);
+
+ struct float_zoo z;
+ memset (&z, 0xf0, sizeof (z));
+
+ /* Call the JIT-generated function. */
+ test_float_types (&z);
+
+ /* Verify that it correctly wrote to the various fields. */
+ gcc_jit_context *info_ctxt = gcc_jit_context_acquire ();
+ gcc_jit_target_info *target_info = gcc_jit_context_get_target_info (info_ctxt);
+ if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT16))
+ CHECK_VALUE (z.m_float16, (_Float16)3.141);
+ if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT32))
+ CHECK_VALUE (z.m_float32, (_Float32)3.141);
+ if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT64))
+ CHECK_VALUE (z.m_float64, (_Float64)3.141);
+ if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT128))
+ CHECK_VALUE (z.m_float128, (__float128)3.141);
+
+ if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT16))
+ CHECK_VALUE (gcc_jit_type_get_size (gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT16)), sizeof (_Float16));
+ if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT32))
+ CHECK_VALUE (gcc_jit_type_get_size (gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT32)), sizeof (_Float32));
+ if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT64))
+ CHECK_VALUE (gcc_jit_type_get_size (gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT64)), sizeof (_Float64));
+ if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT128))
+ CHECK_VALUE (gcc_jit_type_get_size (gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT128)), sizeof (__float128));
+}