#include #include #include #include #include "libgccjit.h" #include "harness.h" /********************************************************************** Unary ops **********************************************************************/ static const char * make_test_of_unary_op (gcc_jit_context *ctxt, gcc_jit_type *type, enum gcc_jit_unary_op op, const char *funcname) { /* Make a test function of the form: T test_unary_op (T a) { return OP a; } and return a debug dump of the OP so that the caller can sanity-check the debug dump implementation. */ gcc_jit_param *param_a = gcc_jit_context_new_param (ctxt, NULL, type, "a"); gcc_jit_function *test_fn = gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_EXPORTED, type, funcname, 1, ¶m_a, 0); gcc_jit_rvalue *unary_op = gcc_jit_context_new_unary_op ( ctxt, NULL, op, type, gcc_jit_param_as_rvalue (param_a)); gcc_jit_block *initial = gcc_jit_function_new_block (test_fn, "initial"); gcc_jit_block_end_with_return (initial, NULL, unary_op); return gcc_jit_object_get_debug_string ( gcc_jit_rvalue_as_object (unary_op)); } static void make_tests_of_unary_ops (gcc_jit_context *ctxt) { gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); CHECK_STRING_VALUE ( make_test_of_unary_op (ctxt, int_type, GCC_JIT_UNARY_OP_MINUS, "test_UNARY_OP_MINUS_on_int"), "-(a)"); CHECK_STRING_VALUE ( make_test_of_unary_op (ctxt, int_type, GCC_JIT_UNARY_OP_BITWISE_NEGATE, "test_UNARY_OP_BITWISE_NEGATE_on_int"), "~(a)"); CHECK_STRING_VALUE ( make_test_of_unary_op (ctxt, int_type, GCC_JIT_UNARY_OP_LOGICAL_NEGATE, "test_UNARY_OP_LOGICAL_NEGATE_on_int"), "!(a)"); CHECK_STRING_VALUE ( make_test_of_unary_op (ctxt, int_type, GCC_JIT_UNARY_OP_ABS, "test_UNARY_OP_ABS_on_int"), "abs (a)"); } static void verify_unary_ops (gcc_jit_result *result) { typedef int (*test_fn) (int); test_fn test_UNARY_OP_MINUS_on_int = (test_fn)gcc_jit_result_get_code (result, "test_UNARY_OP_MINUS_on_int"); CHECK_NON_NULL (test_UNARY_OP_MINUS_on_int); CHECK_VALUE (test_UNARY_OP_MINUS_on_int (0), 0); CHECK_VALUE (test_UNARY_OP_MINUS_on_int (42), -42); CHECK_VALUE (test_UNARY_OP_MINUS_on_int (-5), 5); test_fn test_UNARY_OP_BITWISE_NEGATE_on_int = (test_fn)gcc_jit_result_get_code (result, "test_UNARY_OP_BITWISE_NEGATE_on_int"); CHECK_NON_NULL (test_UNARY_OP_BITWISE_NEGATE_on_int); CHECK_VALUE (test_UNARY_OP_BITWISE_NEGATE_on_int (0), ~0); CHECK_VALUE (test_UNARY_OP_BITWISE_NEGATE_on_int (42), ~42); CHECK_VALUE (test_UNARY_OP_BITWISE_NEGATE_on_int (-5), ~-5); test_fn test_UNARY_OP_LOGICAL_NEGATE_on_int = (test_fn)gcc_jit_result_get_code (result, "test_UNARY_OP_LOGICAL_NEGATE_on_int"); CHECK_NON_NULL (test_UNARY_OP_LOGICAL_NEGATE_on_int); CHECK_VALUE (test_UNARY_OP_LOGICAL_NEGATE_on_int (0), 1); CHECK_VALUE (test_UNARY_OP_LOGICAL_NEGATE_on_int (42), 0); CHECK_VALUE (test_UNARY_OP_LOGICAL_NEGATE_on_int (-5), 0); test_fn test_UNARY_OP_ABS_on_int = (test_fn)gcc_jit_result_get_code (result, "test_UNARY_OP_ABS_on_int"); CHECK_NON_NULL (test_UNARY_OP_ABS_on_int); CHECK_VALUE (test_UNARY_OP_ABS_on_int (0), 0); CHECK_VALUE (test_UNARY_OP_ABS_on_int (42), 42); CHECK_VALUE (test_UNARY_OP_ABS_on_int (-5), 5); } /********************************************************************** Binary ops **********************************************************************/ static const char * make_test_of_binary_op (gcc_jit_context *ctxt, gcc_jit_type *type, enum gcc_jit_binary_op op, const char *funcname) { /* Make a test function of the form: T test_binary_op (T a, T b) { return a OP b; } */ gcc_jit_param *param_a = gcc_jit_context_new_param (ctxt, NULL, type, "a"); gcc_jit_param *param_b = gcc_jit_context_new_param (ctxt, NULL, type, "b"); gcc_jit_param *params[] = {param_a, param_b}; gcc_jit_function *test_fn = gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_EXPORTED, type, funcname, 2, params, 0); gcc_jit_rvalue *binary_op = gcc_jit_context_new_binary_op ( ctxt, NULL, op, type, gcc_jit_param_as_rvalue (param_a), gcc_jit_param_as_rvalue (param_b)); gcc_jit_block *initial = gcc_jit_function_new_block (test_fn, "initial"); gcc_jit_block_end_with_return (initial, NULL, binary_op); return gcc_jit_object_get_debug_string ( gcc_jit_rvalue_as_object (binary_op)); } static void make_tests_of_binary_ops (gcc_jit_context *ctxt) { gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); /* Test binary ops. */ CHECK_STRING_VALUE ( make_test_of_binary_op (ctxt, int_type, GCC_JIT_BINARY_OP_PLUS, "test_BINARY_OP_PLUS_on_int"), "a + b"); CHECK_STRING_VALUE ( make_test_of_binary_op (ctxt, int_type, GCC_JIT_BINARY_OP_MINUS, "test_BINARY_OP_MINUS_on_int"), "a - b"); CHECK_STRING_VALUE ( make_test_of_binary_op (ctxt, int_type, GCC_JIT_BINARY_OP_MULT, "test_BINARY_OP_MULT_on_int"), "a * b"); CHECK_STRING_VALUE ( make_test_of_binary_op (ctxt, int_type, GCC_JIT_BINARY_OP_DIVIDE, "test_BINARY_OP_DIVIDE_on_int"), "a / b"); /* TODO: test for DIVIDE on float or double */ CHECK_STRING_VALUE ( make_test_of_binary_op (ctxt, int_type, GCC_JIT_BINARY_OP_MODULO, "test_BINARY_OP_MODULO_on_int"), "a % b"); CHECK_STRING_VALUE ( make_test_of_binary_op (ctxt, int_type, GCC_JIT_BINARY_OP_BITWISE_AND, "test_BINARY_OP_BITWISE_AND_on_int"), "a & b"); CHECK_STRING_VALUE ( make_test_of_binary_op (ctxt, int_type, GCC_JIT_BINARY_OP_BITWISE_XOR, "test_BINARY_OP_BITWISE_XOR_on_int"), "a ^ b"); CHECK_STRING_VALUE ( make_test_of_binary_op (ctxt, int_type, GCC_JIT_BINARY_OP_BITWISE_OR, "test_BINARY_OP_BITWISE_OR_on_int"), "a | b"); CHECK_STRING_VALUE ( make_test_of_binary_op (ctxt, int_type, GCC_JIT_BINARY_OP_LOGICAL_AND, "test_BINARY_OP_LOGICAL_AND_on_int"), "a && b"); CHECK_STRING_VALUE ( make_test_of_binary_op (ctxt, int_type, GCC_JIT_BINARY_OP_LOGICAL_OR, "test_BINARY_OP_LOGICAL_OR_on_int"), "a || b"); CHECK_STRING_VALUE ( make_test_of_binary_op (ctxt, int_type, GCC_JIT_BINARY_OP_LSHIFT, "test_BINARY_OP_LSHIFT_on_int"), "a << b"); CHECK_STRING_VALUE ( make_test_of_binary_op (ctxt, int_type, GCC_JIT_BINARY_OP_RSHIFT, "test_BINARY_OP_RSHIFT_on_int"), "a >> b"); } static void verify_binary_ops (gcc_jit_result *result) { typedef int (*test_fn) (int, int); test_fn test_BINARY_OP_PLUS_on_int = (test_fn)gcc_jit_result_get_code (result, "test_BINARY_OP_PLUS_on_int"); CHECK_NON_NULL (test_BINARY_OP_PLUS_on_int); CHECK_VALUE (test_BINARY_OP_PLUS_on_int (0, 0), 0); CHECK_VALUE (test_BINARY_OP_PLUS_on_int (1, 2), 3); CHECK_VALUE (test_BINARY_OP_PLUS_on_int (100, -1), 99); CHECK_VALUE (test_BINARY_OP_PLUS_on_int (-1, -4), -5); test_fn test_BINARY_OP_MINUS_on_int = (test_fn)gcc_jit_result_get_code (result, "test_BINARY_OP_MINUS_on_int"); CHECK_NON_NULL (test_BINARY_OP_MINUS_on_int); CHECK_VALUE (test_BINARY_OP_MINUS_on_int (0, 0), 0); CHECK_VALUE (test_BINARY_OP_MINUS_on_int (1, 2), -1); CHECK_VALUE (test_BINARY_OP_MINUS_on_int (100, -1), 101); CHECK_VALUE (test_BINARY_OP_MINUS_on_int (-1, -4), 3); test_fn test_BINARY_OP_MULT_on_int = (test_fn)gcc_jit_result_get_code (result, "test_BINARY_OP_MULT_on_int"); CHECK_NON_NULL (test_BINARY_OP_MULT_on_int); CHECK_VALUE (test_BINARY_OP_MULT_on_int (0, 0), 0); CHECK_VALUE (test_BINARY_OP_MULT_on_int (1, 2), 2); CHECK_VALUE (test_BINARY_OP_MULT_on_int (100, -1), -100); CHECK_VALUE (test_BINARY_OP_MULT_on_int (-1, -4), 4); CHECK_VALUE (test_BINARY_OP_MULT_on_int (7, 10), 70); test_fn test_BINARY_OP_DIVIDE_on_int = (test_fn)gcc_jit_result_get_code (result, "test_BINARY_OP_DIVIDE_on_int"); CHECK_NON_NULL (test_BINARY_OP_DIVIDE_on_int); CHECK_VALUE (test_BINARY_OP_DIVIDE_on_int (7, 2), 3); CHECK_VALUE (test_BINARY_OP_DIVIDE_on_int (100, -1), (100 / -1)); CHECK_VALUE (test_BINARY_OP_DIVIDE_on_int (-1, -4), (-1 / -4)); CHECK_VALUE (test_BINARY_OP_DIVIDE_on_int (60, 5), 12); /* TODO: test for DIVIDE on float or double */ test_fn test_BINARY_OP_MODULO_on_int = (test_fn)gcc_jit_result_get_code (result, "test_BINARY_OP_MODULO_on_int"); CHECK_NON_NULL (test_BINARY_OP_MODULO_on_int); CHECK_VALUE (test_BINARY_OP_MODULO_on_int (7, 2), 1); CHECK_VALUE (test_BINARY_OP_MODULO_on_int (100, -1), (100 % -1)); CHECK_VALUE (test_BINARY_OP_MODULO_on_int (-1, -4), (-1 % -4)); CHECK_VALUE (test_BINARY_OP_MODULO_on_int (60, 5), 0); test_fn test_BINARY_OP_BITWISE_AND_on_int = (test_fn)gcc_jit_result_get_code (result, "test_BINARY_OP_BITWISE_AND_on_int"); CHECK_NON_NULL (test_BINARY_OP_BITWISE_AND_on_int); CHECK_VALUE (test_BINARY_OP_BITWISE_AND_on_int (0xf0f0, 0x7777), 0x7070); test_fn test_BINARY_OP_BITWISE_XOR_on_int = (test_fn)gcc_jit_result_get_code (result, "test_BINARY_OP_BITWISE_XOR_on_int"); CHECK_NON_NULL (test_BINARY_OP_BITWISE_XOR_on_int); CHECK_VALUE (test_BINARY_OP_BITWISE_XOR_on_int (0xf0f0, 0x7777), 0x8787); test_fn test_BINARY_OP_BITWISE_OR_on_int = (test_fn)gcc_jit_result_get_code (result, "test_BINARY_OP_BITWISE_OR_on_int"); CHECK_NON_NULL (test_BINARY_OP_BITWISE_OR_on_int); CHECK_VALUE (test_BINARY_OP_BITWISE_OR_on_int (0xf0f0, 0x7777), 0xf7f7); test_fn test_BINARY_OP_LOGICAL_AND_on_int = (test_fn)gcc_jit_result_get_code (result, "test_BINARY_OP_LOGICAL_AND_on_int"); CHECK_NON_NULL (test_BINARY_OP_LOGICAL_AND_on_int); CHECK_VALUE (test_BINARY_OP_LOGICAL_AND_on_int (0, 0), 0); CHECK_VALUE (test_BINARY_OP_LOGICAL_AND_on_int (42, 0), 0); CHECK_VALUE (test_BINARY_OP_LOGICAL_AND_on_int (0, -13), 0); CHECK_VALUE (test_BINARY_OP_LOGICAL_AND_on_int (1997, 1998), 1); test_fn test_BINARY_OP_LOGICAL_OR_on_int = (test_fn)gcc_jit_result_get_code (result, "test_BINARY_OP_LOGICAL_OR_on_int"); CHECK_NON_NULL (test_BINARY_OP_LOGICAL_OR_on_int); CHECK_VALUE (test_BINARY_OP_LOGICAL_OR_on_int (0, 0), 0); CHECK_VALUE (test_BINARY_OP_LOGICAL_OR_on_int (42, 0), 1); CHECK_VALUE (test_BINARY_OP_LOGICAL_OR_on_int (0, -13), 1); CHECK_VALUE (test_BINARY_OP_LOGICAL_OR_on_int (1997, 1998), 1); test_fn test_BINARY_OP_LSHIFT_on_int = (test_fn)gcc_jit_result_get_code (result, "test_BINARY_OP_LSHIFT_on_int"); CHECK_NON_NULL (test_BINARY_OP_LSHIFT_on_int); CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (0, 0), 0); CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (0, 1), 0); CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (0, 2), 0); CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (1, 0), 1); CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (1, 1), 2); CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (1, 2), 4); CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (1, 3), 8); CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (3, 0), 3); CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (3, 1), 6); CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (3, 5), 3 * 32); CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (42, 0), 42); CHECK_VALUE (test_BINARY_OP_LSHIFT_on_int (42, 1), 84); test_fn test_BINARY_OP_RSHIFT_on_int = (test_fn)gcc_jit_result_get_code (result, "test_BINARY_OP_RSHIFT_on_int"); CHECK_NON_NULL (test_BINARY_OP_RSHIFT_on_int); CHECK_VALUE (test_BINARY_OP_RSHIFT_on_int (0, 0), 0); CHECK_VALUE (test_BINARY_OP_RSHIFT_on_int (42, 0), 42); CHECK_VALUE (test_BINARY_OP_RSHIFT_on_int (42, 1), 21); CHECK_VALUE (test_BINARY_OP_RSHIFT_on_int (42, 2), 10); } /********************************************************************** Comparisons **********************************************************************/ static const char * make_test_of_comparison (gcc_jit_context *ctxt, gcc_jit_type *type, enum gcc_jit_comparison op, const char *funcname) { /* Make a test function of the form: bool test_comparison_op (T a, T b) { return a OP b; } */ gcc_jit_param *param_a = gcc_jit_context_new_param (ctxt, NULL, type, "a"); gcc_jit_param *param_b = gcc_jit_context_new_param (ctxt, NULL, type, "b"); gcc_jit_param *params[] = {param_a, param_b}; gcc_jit_type *bool_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_BOOL); gcc_jit_function *test_fn = gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_EXPORTED, bool_type, funcname, 2, params, 0); gcc_jit_rvalue *comparison = gcc_jit_context_new_comparison ( ctxt, NULL, op, gcc_jit_param_as_rvalue (param_a), gcc_jit_param_as_rvalue (param_b)); gcc_jit_block *initial = gcc_jit_function_new_block (test_fn, "initial"); gcc_jit_block_end_with_return (initial, NULL, comparison); return gcc_jit_object_get_debug_string ( gcc_jit_rvalue_as_object (comparison)); } static void make_tests_of_comparisons (gcc_jit_context *ctxt) { gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); CHECK_STRING_VALUE ( make_test_of_comparison (ctxt, int_type, GCC_JIT_COMPARISON_EQ, "test_COMPARISON_EQ_on_int"), "a == b"); CHECK_STRING_VALUE ( make_test_of_comparison (ctxt, int_type, GCC_JIT_COMPARISON_NE, "test_COMPARISON_NE_on_int"), "a != b"); CHECK_STRING_VALUE ( make_test_of_comparison (ctxt, int_type, GCC_JIT_COMPARISON_LT, "test_COMPARISON_LT_on_int"), "a < b"); CHECK_STRING_VALUE ( make_test_of_comparison (ctxt, int_type, GCC_JIT_COMPARISON_LE, "test_COMPARISON_LE_on_int"), "a <= b"); CHECK_STRING_VALUE ( make_test_of_comparison (ctxt, int_type, GCC_JIT_COMPARISON_GT, "test_COMPARISON_GT_on_int"), "a > b"); CHECK_STRING_VALUE ( make_test_of_comparison (ctxt, int_type, GCC_JIT_COMPARISON_GE, "test_COMPARISON_GE_on_int"), "a >= b"); } static void verify_comparisons (gcc_jit_result *result) { typedef bool (*test_fn) (int, int); test_fn test_COMPARISON_EQ_on_int = (test_fn)gcc_jit_result_get_code (result, "test_COMPARISON_EQ_on_int"); CHECK_NON_NULL (test_COMPARISON_EQ_on_int); CHECK_VALUE (test_COMPARISON_EQ_on_int (0, 0), 1); CHECK_VALUE (test_COMPARISON_EQ_on_int (1, 2), 0); test_fn test_COMPARISON_NE_on_int = (test_fn)gcc_jit_result_get_code (result, "test_COMPARISON_NE_on_int"); CHECK_NON_NULL (test_COMPARISON_NE_on_int); CHECK_VALUE (test_COMPARISON_NE_on_int (0, 0), 0); CHECK_VALUE (test_COMPARISON_NE_on_int (1, 2), 1); test_fn test_COMPARISON_LT_on_int = (test_fn)gcc_jit_result_get_code (result, "test_COMPARISON_LT_on_int"); CHECK_NON_NULL (test_COMPARISON_LT_on_int); CHECK_VALUE (test_COMPARISON_LT_on_int (0, 0), 0); CHECK_VALUE (test_COMPARISON_LT_on_int (1, 2), 1); CHECK_VALUE (test_COMPARISON_LT_on_int (2, 1), 0); CHECK_VALUE (test_COMPARISON_LT_on_int (-2, 1), 1); test_fn test_COMPARISON_LE_on_int = (test_fn)gcc_jit_result_get_code (result, "test_COMPARISON_LE_on_int"); CHECK_NON_NULL (test_COMPARISON_LE_on_int); CHECK_VALUE (test_COMPARISON_LE_on_int (0, 0), 1); CHECK_VALUE (test_COMPARISON_LE_on_int (1, 2), 1); CHECK_VALUE (test_COMPARISON_LE_on_int (2, 1), 0); test_fn test_COMPARISON_GT_on_int = (test_fn)gcc_jit_result_get_code (result, "test_COMPARISON_GT_on_int"); CHECK_NON_NULL (test_COMPARISON_GT_on_int); CHECK_VALUE (test_COMPARISON_GT_on_int (0, 0), 0); CHECK_VALUE (test_COMPARISON_GT_on_int (1, 2), 0); CHECK_VALUE (test_COMPARISON_GT_on_int (2, 1), 1); test_fn test_COMPARISON_GE_on_int = (test_fn)gcc_jit_result_get_code (result, "test_COMPARISON_GE_on_int"); CHECK_NON_NULL (test_COMPARISON_GE_on_int); CHECK_VALUE (test_COMPARISON_GE_on_int (0, 0), 1); CHECK_VALUE (test_COMPARISON_GE_on_int (1, 2), 0); CHECK_VALUE (test_COMPARISON_GE_on_int (2, 1), 1); } /********************************************************************** Casts **********************************************************************/ static const char* make_test_of_cast (gcc_jit_context *ctxt, gcc_jit_type *input_type, gcc_jit_type *output_type, const char *funcname) { /* Make a test function of the form: OUTPUT_TYPE test_cast_* (INPUT_TYPE a) { return (OUTPUT_TYPE)a; } */ gcc_jit_param *param_a = gcc_jit_context_new_param (ctxt, NULL, input_type, "a"); gcc_jit_param *params[] = {param_a}; gcc_jit_function *test_fn = gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_EXPORTED, output_type, funcname, 1, params, 0); gcc_jit_rvalue *cast = gcc_jit_context_new_cast ( ctxt, NULL, gcc_jit_param_as_rvalue (param_a), output_type); gcc_jit_block *initial = gcc_jit_function_new_block (test_fn, "initial"); gcc_jit_block_end_with_return (initial, NULL, cast); return gcc_jit_object_get_debug_string ( gcc_jit_rvalue_as_object (cast)); } /* For use by test_cast_from_array_of_ints_to_int_ptr. */ extern int called_pointer_checking_function (int *ints) { CHECK_VALUE (ints[0], 10); CHECK_VALUE (ints[1], 4); return ints[0] * ints[1]; } static void make_tests_of_casts (gcc_jit_context *ctxt) { gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); gcc_jit_type *long_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_LONG); gcc_jit_type *float_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT); gcc_jit_type *bool_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_BOOL); gcc_jit_type *array_int_type = gcc_jit_context_new_array_type (ctxt, NULL, int_type, 2); gcc_jit_type *int_ptr_type = gcc_jit_type_get_pointer (int_type); /* float/int conversions */ CHECK_STRING_VALUE ( make_test_of_cast (ctxt, float_type, int_type, "test_cast_from_float_to_int"), "(int)a"); CHECK_STRING_VALUE ( make_test_of_cast (ctxt, int_type, float_type, "test_cast_from_int_to_float"), "(float)a"); /* bool/int conversions */ CHECK_STRING_VALUE ( make_test_of_cast (ctxt, bool_type, int_type, "test_cast_from_bool_to_int"), "(int)a"); CHECK_STRING_VALUE ( make_test_of_cast (ctxt, int_type, bool_type, "test_cast_from_int_to_bool"), "(bool)a"); /* bool/long conversions */ CHECK_STRING_VALUE ( make_test_of_cast (ctxt, bool_type, long_type, "test_cast_from_bool_to_long"), "(long)a"); CHECK_STRING_VALUE ( make_test_of_cast (ctxt, long_type, bool_type, "test_cast_from_long_to_bool"), "(bool)a"); /* array/ptr conversions */ { gcc_jit_function *test_fn = gcc_jit_context_new_function ( ctxt, NULL, GCC_JIT_FUNCTION_EXPORTED, int_type, "test_cast_from_array_of_ints_to_int_ptr", 0, NULL, 0); /* Equivalent to: int test_cast_from_array_of_ints_to_int_ptr (void) { int array[2]; array[0] = 10; array[1] = 4; return called_pointer_checking_function (array); } */ gcc_jit_param *param_ints = gcc_jit_context_new_param (ctxt, NULL, int_ptr_type, "ints"); gcc_jit_function *called_fn = gcc_jit_context_new_function ( ctxt, NULL, GCC_JIT_FUNCTION_IMPORTED, int_type, "called_pointer_checking_function", 1, ¶m_ints, 0); gcc_jit_lvalue *array = gcc_jit_function_new_local (test_fn, NULL, array_int_type, "array"); gcc_jit_block *block = gcc_jit_function_new_block (test_fn, "block"); /* array[0] = 10; */ gcc_jit_block_add_assignment ( block, NULL, gcc_jit_context_new_array_access ( ctxt, NULL, gcc_jit_lvalue_as_rvalue (array), gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 0)), gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 10)); /* array[1] = 4; */ gcc_jit_block_add_assignment ( block, NULL, gcc_jit_context_new_array_access ( ctxt, NULL, gcc_jit_lvalue_as_rvalue (array), gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 1)), gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 4)); gcc_jit_rvalue *cast = gcc_jit_context_new_cast ( ctxt, NULL, /* We need a get_address here. */ gcc_jit_lvalue_get_address (array, NULL), int_ptr_type); gcc_jit_block_end_with_return ( block, NULL, gcc_jit_context_new_call ( ctxt, NULL, called_fn, 1, &cast)); CHECK_STRING_VALUE ( gcc_jit_object_get_debug_string ( gcc_jit_rvalue_as_object (cast)), "(int *)&array"); } } static void verify_casts (gcc_jit_result *result) { /* float to int */ { typedef int (*fn_type) (float); fn_type test_cast_from_float_to_int = (fn_type)gcc_jit_result_get_code (result, "test_cast_from_float_to_int"); CHECK_NON_NULL (test_cast_from_float_to_int); CHECK_VALUE (test_cast_from_float_to_int (4.2), 4); } /* int to float */ { typedef float (*fn_type) (int); fn_type test_cast_from_int_to_float = (fn_type)gcc_jit_result_get_code (result, "test_cast_from_int_to_float"); CHECK_NON_NULL (test_cast_from_int_to_float); CHECK_VALUE (test_cast_from_int_to_float (4), 4.0); } /* bool to int */ { typedef int (*fn_type) (bool); fn_type test_cast_from_bool_to_int = (fn_type)gcc_jit_result_get_code (result, "test_cast_from_bool_to_int"); CHECK_NON_NULL (test_cast_from_bool_to_int); CHECK_VALUE (test_cast_from_bool_to_int (0), 0); CHECK_VALUE (test_cast_from_bool_to_int (1), 1); } /* int to bool */ { typedef bool (*fn_type) (int); fn_type test_cast_from_int_to_bool = (fn_type)gcc_jit_result_get_code (result, "test_cast_from_int_to_bool"); CHECK_NON_NULL (test_cast_from_int_to_bool); CHECK_VALUE (test_cast_from_int_to_bool (0), 0); CHECK_VALUE (test_cast_from_int_to_bool (1), 1); } /* bool to long */ { typedef long (*fn_type) (bool); fn_type test_cast_from_bool_to_long = (fn_type)gcc_jit_result_get_code (result, "test_cast_from_bool_to_long"); CHECK_NON_NULL (test_cast_from_bool_to_long); CHECK_VALUE (test_cast_from_bool_to_long (0), 0); CHECK_VALUE (test_cast_from_bool_to_long (1), 1); } /* long to bool */ { typedef bool (*fn_type) (long); fn_type test_cast_from_long_to_bool = (fn_type)gcc_jit_result_get_code (result, "test_cast_from_long_to_bool"); CHECK_NON_NULL (test_cast_from_long_to_bool); CHECK_VALUE (test_cast_from_long_to_bool (0), 0); CHECK_VALUE (test_cast_from_long_to_bool (1), 1); } /* array to ptr */ { typedef int (*fn_type) (void); fn_type test_cast_from_array_of_ints_to_int_ptr = (fn_type)gcc_jit_result_get_code ( result, "test_cast_from_array_of_ints_to_int_ptr"); CHECK_NON_NULL (test_cast_from_array_of_ints_to_int_ptr); CHECK_VALUE (test_cast_from_array_of_ints_to_int_ptr (), 40); } } /********************************************************************** Dereferences **********************************************************************/ static void make_tests_of_dereferences (gcc_jit_context *ctxt) { /* int test_dereference_read (int *ptr) { return *ptr; } void test_dereference_write (int *ptr, int i) { *ptr = i; } */ gcc_jit_type *void_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); gcc_jit_type *int_ptr_type = gcc_jit_type_get_pointer (int_type); { gcc_jit_param *param_ptr = gcc_jit_context_new_param (ctxt, NULL, int_ptr_type, "ptr"); gcc_jit_function *test_dereference_read = gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_EXPORTED, int_type, "test_dereference_read", 1, ¶m_ptr, 0); gcc_jit_block *initial = gcc_jit_function_new_block (test_dereference_read, "initial"); gcc_jit_block_end_with_return ( initial, NULL, gcc_jit_lvalue_as_rvalue ( gcc_jit_rvalue_dereference ( gcc_jit_param_as_rvalue (param_ptr), NULL))); } { gcc_jit_param *param_ptr = gcc_jit_context_new_param (ctxt, NULL, int_ptr_type, "ptr"); gcc_jit_param *param_i = gcc_jit_context_new_param (ctxt, NULL, int_type, "i"); gcc_jit_param *params[] = {param_ptr, param_i}; gcc_jit_function *test_dereference_write = gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_EXPORTED, void_type, "test_dereference_write", 2, params, 0); gcc_jit_block *initial = gcc_jit_function_new_block (test_dereference_write, "initial"); gcc_jit_block_add_assignment ( initial, NULL, gcc_jit_rvalue_dereference ( gcc_jit_param_as_rvalue (param_ptr), NULL), gcc_jit_param_as_rvalue (param_i)); gcc_jit_block_end_with_void_return (initial, NULL); } } static void verify_dereferences (gcc_jit_result *result) { int a = 42; int b = -99; { typedef int (*test_read) (int *); test_read test_dereference_read = (test_read)gcc_jit_result_get_code (result, "test_dereference_read"); CHECK_NON_NULL (test_dereference_read); CHECK_VALUE (test_dereference_read (&a), 42); CHECK_VALUE (test_dereference_read (&b), -99); } { typedef void (*test_write) (int *, int); test_write test_dereference_write = (test_write)gcc_jit_result_get_code (result, "test_dereference_write"); CHECK_NON_NULL (test_dereference_write); test_dereference_write (&a, -55); CHECK_VALUE (a, -55); test_dereference_write (&b, 404); CHECK_VALUE (b, 404); } } /********************************************************************** gcc_jit_lvalue_get_address **********************************************************************/ int test_global; static void make_test_of_get_address (gcc_jit_context *ctxt) { /* void *test_get_address (void) { return &test_global; } */ gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); gcc_jit_lvalue *test_global = gcc_jit_context_new_global ( ctxt, NULL, GCC_JIT_GLOBAL_IMPORTED, int_type, "test_global"); gcc_jit_type *void_ptr_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID_PTR); gcc_jit_function *test_get_address = gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_EXPORTED, void_ptr_type, "test_get_address", 0, NULL, 0); gcc_jit_block *initial = gcc_jit_function_new_block (test_get_address, "initial"); gcc_jit_block_end_with_return ( initial, NULL, gcc_jit_lvalue_get_address ( test_global, NULL)); } static void verify_get_address (gcc_jit_result *result) { typedef void *(*test_fn) (void); test_fn test_get_address = (test_fn)gcc_jit_result_get_code (result, "test_get_address"); CHECK_NON_NULL (test_get_address); CHECK_VALUE (test_get_address (), &test_global); } /********************************************************************** Vector values **********************************************************************/ static void make_test_of_vectors (gcc_jit_context *ctxt) { gcc_jit_type *scalar_type; gcc_jit_type *vec_type; gcc_jit_rvalue *elements[4]; scalar_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); vec_type = gcc_jit_type_get_vector (scalar_type, 4); elements[0] = gcc_jit_context_new_rvalue_from_int (ctxt, scalar_type, 1); elements[1] = gcc_jit_context_new_rvalue_from_int (ctxt, scalar_type, -2); elements[2] = gcc_jit_context_new_rvalue_from_int (ctxt, scalar_type, 3); elements[3] = gcc_jit_context_new_rvalue_from_int (ctxt, scalar_type, -4); gcc_jit_rvalue *vec_rvalue = gcc_jit_context_new_rvalue_from_vector (ctxt, NULL, vec_type, 4, elements); CHECK_STRING_VALUE ( gcc_jit_object_get_debug_string ( gcc_jit_rvalue_as_object (vec_rvalue)), "{(int)1, (int)-2, (int)3, (int)-4}"); } /********************************************************************** Code for harness **********************************************************************/ void create_code (gcc_jit_context *ctxt, void *user_data) { make_tests_of_unary_ops (ctxt); make_tests_of_binary_ops (ctxt); make_tests_of_comparisons (ctxt); make_tests_of_casts (ctxt); make_tests_of_dereferences (ctxt); make_test_of_get_address (ctxt); make_test_of_vectors (ctxt); } void verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) { CHECK_NON_NULL (result); verify_unary_ops (result); verify_binary_ops (result); verify_comparisons (result); verify_casts (result); verify_dereferences (result); verify_get_address (result); }