Add a tester for V-bit propagation through IROps.
The tester is located in memcheck/tests/vbit-test.
It needs the following support on the valgrind / VEX side:
(1) a new client request VG_USERREQ__VEX_INIT_FOR_IRI
(2) a new "special instruction" on all architectures inserted via
VALGRIND_VEX_INJECT_IR
(3) VEX changes to detect the special insn and insert IR (ir_inject.c)
The README file in vbit-test has some more information.
See also VEX r2490. Fixes bugzilla #300102.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12906 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/memcheck/tests/vbit-test/ternary.c b/memcheck/tests/vbit-test/ternary.c
new file mode 100644
index 0000000..8365b24
--- /dev/null
+++ b/memcheck/tests/vbit-test/ternary.c
@@ -0,0 +1,62 @@
+/* -*- mode: C; c-basic-offset: 3; -*- */
+
+#include <assert.h>
+#include "vtest.h"
+
+
+/* Check the result of a ternary operation. */
+static void
+check_result_for_ternary(const irop_t *op, const test_data_t *data)
+{
+ const opnd_t *result = &data->result;
+ const opnd_t *opnd1 = &data->opnds[0];
+ const opnd_t *opnd2 = &data->opnds[1];
+ const opnd_t *opnd3 = &data->opnds[2];
+ vbits_t expected_vbits;
+
+ /* Only handle those undef-kinds that actually occur. */
+ switch (op->undef_kind) {
+ case UNDEF_ALL:
+ expected_vbits = undefined_vbits(result->vbits.num_bits);
+ break;
+
+ case UNDEF_SAME:
+ // SAME with respect to the 1-bits in all operands
+ expected_vbits = or_vbits(or_vbits(opnd1->vbits, opnd2->vbits),
+ opnd3->vbits);
+ break;
+
+ default:
+ panic(__func__);
+ }
+
+ if (! equal_vbits(result->vbits, expected_vbits))
+ complain(op, data, expected_vbits);
+}
+
+
+void
+test_ternary_op(const irop_t *op, test_data_t *data)
+{
+ unsigned num_input_bits, i, bitpos;
+ opnd_t *opnds = data->opnds;
+
+ /* For each operand, set a single bit to undefined and observe how
+ that propagates to the output. Do this for all bits in each
+ operand. */
+ for (i = 0; i < 3; ++i) {
+ num_input_bits = bitsof_irtype(opnds[i].type);
+
+ opnds[0].vbits = defined_vbits(bitsof_irtype(opnds[0].type));
+ opnds[1].vbits = defined_vbits(bitsof_irtype(opnds[1].type));
+ opnds[2].vbits = defined_vbits(bitsof_irtype(opnds[2].type));
+
+ for (bitpos = 0; bitpos < num_input_bits; ++bitpos) {
+ opnds[i].vbits = onehot_vbits(bitpos, bitsof_irtype(opnds[i].type));
+
+ valgrind_execute_test(op, data);
+
+ check_result_for_ternary(op, data);
+ }
+ }
+}