blob: f9cc64fd4db3a69d0ca5cb1db1bfb638456f76ab [file] [log] [blame]
#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, &param_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, &param_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, &param_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);
}