diff options
Diffstat (limited to 'gcc/testsuite/jit.dg/test-expressions.c')
-rw-r--r-- | gcc/testsuite/jit.dg/test-expressions.c | 896 |
1 files changed, 896 insertions, 0 deletions
diff --git a/gcc/testsuite/jit.dg/test-expressions.c b/gcc/testsuite/jit.dg/test-expressions.c new file mode 100644 index 000000000000..eb986f38e253 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-expressions.c @@ -0,0 +1,896 @@ +#include <stdlib.h> +#include <stdio.h> +#include <stddef.h> +#include <stdbool.h> + +#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)"); +} + +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); + +} + +/********************************************************************** + 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 *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"); + + /* 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); + } + + /* 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, + 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); +} + +/********************************************************************** + 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); +} + +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); +} |