From adfd3e03b1680d1180ccb892f3a4c38dba517855 Mon Sep 17 00:00:00 2001 From: Carl Love Date: Fri, 16 Nov 2012 18:58:08 +0000 Subject: [PATCH] Valgrind, V-bit tester: Add support for Iop_CmpORD class iops The Iop_CmpORD class of iops support the POWER specific comparison instructions. The instructions take two 32-bit or 64-bit operands and produce a result of the same size. However, only the lower bits of the result are set by the instruction. The bits are set by the instruction to indicate if the comparison is "less then", "greater then", or "equal". This patch adds support to the V-bit tester to verify the propagation of the undefined bits in the inputs to the output for the Iop_CmpORd iops. The output bits are always set to undefined if any of the input bits are not defined. This patch is for bugzilla 310169 git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13123 --- memcheck/tests/vbit-test/binary.c | 10 +++++++++- memcheck/tests/vbit-test/irops.c | 8 ++++---- memcheck/tests/vbit-test/vbits.c | 28 ++++++++++++++++++++++++++++ memcheck/tests/vbit-test/vbits.h | 1 + memcheck/tests/vbit-test/vtest.h | 2 ++ 5 files changed, 44 insertions(+), 5 deletions(-) diff --git a/memcheck/tests/vbit-test/binary.c b/memcheck/tests/vbit-test/binary.c index 78afc9bb4..98cbe25e4 100644 --- a/memcheck/tests/vbit-test/binary.c +++ b/memcheck/tests/vbit-test/binary.c @@ -44,7 +44,6 @@ and_combine(vbits_t v1, vbits_t v2, value_t val2, int invert_val2) return new; } - /* Check the result of a binary operation. */ static void check_result_for_binary(const irop_t *op, const test_data_t *data) @@ -155,6 +154,15 @@ check_result_for_binary(const irop_t *op, const test_data_t *data) break; } + case UNDEF_ORD: + /* Set expected_vbits for the Iop_CmpORD category of iops. + * If any of the input bits is undefined the least significant + * three bits in the result will be set, i.e. 0xe. + */ + expected_vbits = cmpord_vbits(opnd1->vbits.num_bits, + opnd2->vbits.num_bits); + break; + default: panic(__func__); } diff --git a/memcheck/tests/vbit-test/irops.c b/memcheck/tests/vbit-test/irops.c index 9412c6fe6..0f65fe7af 100644 --- a/memcheck/tests/vbit-test/irops.c +++ b/memcheck/tests/vbit-test/irops.c @@ -104,10 +104,10 @@ static irop_t irops[] = { { DEFOP(Iop_Left32, UNDEF_UNKNOWN), }, // not supported by mc_translate { DEFOP(Iop_Left64, UNDEF_UNKNOWN), }, // not supported by mc_translate { DEFOP(Iop_Max32U, UNDEF_UNKNOWN), }, // not supported by mc_translate - { DEFOP(Iop_CmpORD32U, UNDEF_UNKNOWN), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0 }, // FIXME: add support in vbit-test - { DEFOP(Iop_CmpORD64U, UNDEF_UNKNOWN), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0 }, // FIXME: add support in vbit-test - { DEFOP(Iop_CmpORD32S, UNDEF_UNKNOWN), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0 }, // FIXME: add support in vbit-test - { DEFOP(Iop_CmpORD64S, UNDEF_UNKNOWN), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0 }, // FIXME: add support in vbit-test + { DEFOP(Iop_CmpORD32U, UNDEF_ORD), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0 }, // support added in vbit-test + { DEFOP(Iop_CmpORD64U, UNDEF_ORD), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0 }, // support added in vbit-test + { DEFOP(Iop_CmpORD32S, UNDEF_ORD), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0 }, // support added in vbit-test + { DEFOP(Iop_CmpORD64S, UNDEF_ORD), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0 }, // support added in vbit-test { DEFOP(Iop_DivU32, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0 }, { DEFOP(Iop_DivS32, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0 }, { DEFOP(Iop_DivU64, UNDEF_ALL), .s390x = 0, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 0, .mips32 = 0 }, // ppc32 asserts diff --git a/memcheck/tests/vbit-test/vbits.c b/memcheck/tests/vbit-test/vbits.c index 503d8493e..bea20c14d 100644 --- a/memcheck/tests/vbit-test/vbits.c +++ b/memcheck/tests/vbit-test/vbits.c @@ -740,3 +740,31 @@ sar_vbits(vbits_t v, unsigned shift_amount) new = left_vbits(new, new.num_bits); return new; } + +/* Return a value for the POWER Iop_CmpORD class iops */ +vbits_t +cmpord_vbits(unsigned v1_num_bits, unsigned v2_num_bits) +{ + vbits_t new = { .num_bits = v1_num_bits }; + + /* Size of values being compared must be the same */ + assert( v1_num_bits == v2_num_bits); + + /* Comparison only produces 32-bit or 64-bit value where + * the lower 3 bits are set to indicate, less than, equal and greater then. + */ + switch (v1_num_bits) { + case 32: + new.bits.u32 = 0xE; + break; + + case 64: + new.bits.u64 = 0xE; + break; + + default: + panic(__func__); + } + + return new; +} diff --git a/memcheck/tests/vbit-test/vbits.h b/memcheck/tests/vbit-test/vbits.h index e79a672ed..0c22f9687 100644 --- a/memcheck/tests/vbit-test/vbits.h +++ b/memcheck/tests/vbit-test/vbits.h @@ -53,5 +53,6 @@ vbits_t shl_vbits(vbits_t, unsigned amount); vbits_t shr_vbits(vbits_t, unsigned amount); vbits_t sar_vbits(vbits_t, unsigned amount); int completely_defined_vbits(vbits_t); +vbits_t cmpord_vbits(unsigned v1_num_bits, unsigned v2_num_bits); #endif // VBITS_H diff --git a/memcheck/tests/vbit-test/vtest.h b/memcheck/tests/vbit-test/vtest.h index bb7b2fd69..8f107b441 100644 --- a/memcheck/tests/vbit-test/vtest.h +++ b/memcheck/tests/vbit-test/vtest.h @@ -53,6 +53,8 @@ typedef enum { UNDEF_OR, // bitwise OR operation UNDEF_AND, // bitwise AND operation + UNDEF_ORD, // Iop_CmpORD compare + // For IROps I don't know anything about UNDEF_UNKNOWN } undef_t;