#include <stdint.h> // UINT64_MAX
#include "vtest.h"
-static void check_result(const irop_t *, const test_data_t *);
+static uint64_t get_expected_value(const irop_t *, const test_data_t *);
static void run_tests(const irop_t *, test_data_t *);
static void run_shift_tests(const irop_t *, test_data_t *);
static int is_shift_op(IROp);
if (is_division_op(op->op) && opnd_r->value == 0) continue;
- valgrind_execute_test(op, data);
- check_result(op, data);
+ valgrind_execute_test(op, data, get_expected_value(op, data));
}
}
}
if (is_division_op(op->op) && opnd_r->value == 0) continue;
- valgrind_execute_test(op, data);
- check_result(op, data);
+ valgrind_execute_test(op, data, get_expected_value(op, data));
}
}
for (unsigned j = 0; j < max_shift_amount; ++j) {
opnd_r->value = j;
- valgrind_execute_test(op, data);
- check_result(op, data);
+ valgrind_execute_test(op, data, get_expected_value(op, data));
}
}
opnd_l->value = get_random_value(opnd_l->type);
opnd_r->value = get_random_value(opnd_r->type) & max_shift_amount;
- valgrind_execute_test(op, data);
- check_result(op, data);
+ valgrind_execute_test(op, data, get_expected_value(op, data));
}
}
}
-/* Check the result of a binary operation. */
-static void
-check_result(const irop_t *op, const test_data_t *data)
+/* Compute the expected result of a binary operation. */
+static uint64_t
+get_expected_value(const irop_t *op, const test_data_t *data)
{
- uint64_t result = data->result.value;
uint64_t opnd_l = data->opnds[0].value;
uint64_t opnd_r = data->opnds[1].value;
uint64_t expected;
panic(__func__);
}
- if (verbose > 1) {
- printf("expected: value = ");
- print_value(stdout, expected, bitsof_irtype(data->result.type));
- printf("\n");
- }
-
- int ok = 1;
- switch (data->result.type) {
- case Ity_I1: ok = result == expected; break;
- case Ity_I8: ok = result == expected; break;
- case Ity_I16: ok = result == expected; break;
- case Ity_I32: ok = result == expected; break;
- case Ity_I64: ok = result == expected; break;
- default:
- panic(__func__);
- }
-
- if (! ok)
- complain(op, data, expected);
+ return expected;
}
test_data_t *data = new_test_data(op);
- IRICB iricb = new_iricb(op, data);
+ IRICB *iricb = new_iricb(op, data);
- valgrind_vex_init_for_iri(&iricb);
+ valgrind_vex_init_for_iri(iricb);
switch (op->num_opnds) {
case 1:
#include <stdint.h> // UINT64_MAX
#include "vtest.h"
-static void check_result(const irop_t *, const test_data_t *);
static void run_selected_tests(const irop_t *, test_data_t *);
static void run_random_tests(const irop_t *, test_data_t *);
+static uint64_t get_expected_value(const irop_t *, const test_data_t *);
static uint64_t left(uint64_t, unsigned);
static uint32_t popcount(uint64_t);
static uint32_t clz(uint64_t, unsigned);
for (unsigned i = 0; i <= max; ++i) {
opnd->value = i;
- valgrind_execute_test(op, data);
- check_result(op, data);
+ valgrind_execute_test(op, data, get_expected_value(op, data));
}
break;
}
for (unsigned i = 0; i < num_val; ++i) {
opnd->value = values[i];
- valgrind_execute_test(op, data);
- check_result(op, data);
+ valgrind_execute_test(op, data, get_expected_value(op, data));
}
}
for (unsigned i = 0; i < num_random_tests; ++i) {
opnd->value = get_random_value(opnd->type);
- valgrind_execute_test(op, data);
- check_result(op, data);
+ valgrind_execute_test(op, data, get_expected_value(op, data));
}
}
-/* Check the result of a unary operation. */
-static void
-check_result(const irop_t *op, const test_data_t *data)
+/* Compute the expected result of a unary operation. */
+static uint64_t
+get_expected_value(const irop_t *op, const test_data_t *data)
{
- uint64_t result = data->result.value;
uint64_t opnd = data->opnds[0].value;
uint64_t expected;
panic("%s: operator %s not handled\n", __func__, op->name);
}
- if (verbose > 1) {
- printf("expected: value = ");
- print_value(stdout, expected, bitsof_irtype(data->result.type));
- printf("\n");
- }
-
- int ok = 1;
- switch (data->result.type) {
- case Ity_I1: ok = result == expected; break;
- case Ity_I8: ok = result == expected; break;
- case Ity_I16: ok = result == expected; break;
- case Ity_I32: ok = result == expected; break;
- case Ity_I64: ok = result == expected; break;
- default:
- panic(__func__);
- }
-
- if (! ok)
- complain(op, data, expected);
+ return expected;
}
}
-/* Issue a complaint because the result of an operation differs from what
- was expected. */
-void
-complain(const irop_t *op, const test_data_t *data, uint64_t expected)
-{
- fprintf(stderr, "*** Incorrect result for operator %s\n", op->name);
-
- for (unsigned i = 0; i < op->num_opnds; ++i) {
- fprintf(stderr, " opnd %u: ", i);
- print_opnd(stderr, &data->opnds[i]);
- fprintf(stderr, "\n");
- }
- fprintf(stderr, " result: ");
- print_opnd(stderr, &data->result);
- fprintf(stderr, "\n");
- fprintf(stderr, " expect: ");
- print_value(stderr, expected, bitsof_irtype(op->result_type));
- fprintf(stderr, "\n");
-}
-
-
void
print_value(FILE *fp, uint64_t val, unsigned num_bits)
{
}
-void
-print_opnd(FILE *fp, const opnd_t *opnd)
-{
- fprintf(fp, "value = ");
- print_value(fp, opnd->value, bitsof_irtype(opnd->type));
-}
-
-
unsigned
bitsof_irtype(IRType ty)
{
#include "valgrind.h" // VALGRIND_VEX_INJECT_IR
#include "vtest.h"
+static IRICB iricb;
/* Return a completely initialised control block */
-IRICB
+IRICB *
new_iricb(const irop_t *op, test_data_t *data)
{
IRICB_iropt_payload cb;
cb.num_operands = op->num_opnds;
- return (IRICB) { .kind = IRICB_iropt, .iropt = cb };
+ iricb.kind = IRICB_iropt;
+ iricb.iropt = cb;
+
+ return &iricb;
}
/* Execute the test under valgrind. Well, yes, we're not really executing
it here, just preparing for it... */
void
-valgrind_execute_test(const irop_t *op, test_data_t *data)
+valgrind_execute_test(const irop_t *op, test_data_t *data, uint64_t expected)
{
- if (verbose > 1)
+ if (verbose > 1) {
printf("---------- Running a test\n");
- for (unsigned i = 0; i < op->num_opnds; ++i) {
- if (verbose > 1) {
- printf("opnd #%u: ", i);
- print_opnd(stdout, &data->opnds[i]);
+ for (unsigned i = 0; i < op->num_opnds; ++i) {
+ const opnd_t *opnd = data->opnds + i;
+ printf("opnd %u: value = ", i);
+ print_value(stdout, opnd->value, bitsof_irtype(opnd->type));
printf("\n");
}
}
valgrind_vex_inject_ir();
+ uint64_t result = data->result.value;
+ unsigned num_result_bits = bitsof_irtype(data->result.type);
if (verbose > 1) {
- printf("result: ");
- print_opnd(stdout, &data->result);
+ printf("result: value = ");
+ print_value(stdout, result, num_result_bits);
printf("\n");
+ printf("expected: value = ");
+ print_value(stdout, expected, num_result_bits);
+ printf("\n");
+ }
+
+ /* Check result */
+ if (result != expected) {
+ fprintf(stderr, "*** Incorrect result for operator %s\n", op->name);
+
+ for (unsigned i = 0; i < op->num_opnds; ++i) {
+ const opnd_t *opnd = data->opnds + i;
+ fprintf(stderr, " opnd %u: ", i);
+ print_value(stderr, opnd->value, bitsof_irtype(opnd->type));
+ fprintf(stderr, "\n");
+ }
+ fprintf(stderr, " result: ");
+ print_value(stderr, result, num_result_bits);
+ fprintf(stderr, "\n");
+ fprintf(stderr, " expect: ");
+ print_value(stderr, expected, num_result_bits);
+ fprintf(stderr, "\n");
}
}
/* Function prototypes */
-void print_opnd(FILE *, const opnd_t *);
void print_value(FILE *, uint64_t, unsigned);
void test_unary_op(const irop_t *, test_data_t *);
void test_binary_op(const irop_t *, test_data_t *);
void valgrind_vex_init_for_iri(IRICB *);
-void valgrind_execute_test(const irop_t *, test_data_t *);
+void valgrind_execute_test(const irop_t *, test_data_t *, uint64_t);
-IRICB new_iricb(const irop_t *, test_data_t *);
+IRICB *new_iricb(const irop_t *, test_data_t *);
void panic(const char *, ...) __attribute__((noreturn));
-void complain(const irop_t *, const test_data_t *, uint64_t expected);
unsigned bitsof_irtype(IRType);
uint64_t get_random_value(IRType);