From: Florian Krohm Date: Thu, 13 Sep 2012 19:41:12 +0000 (+0000) Subject: Adjust the vbit tester to deal with shift operations that require X-Git-Tag: svn/VALGRIND_3_9_0~689 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f9979eceb16425505a246f13ff283cdbe93cf538;p=thirdparty%2Fvalgrind.git Adjust the vbit tester to deal with shift operations that require an immediate constant as the shift amount. This is needed for powerpc Iop_ShlD64 etc. What it basically means that we do not iterate over the bits in the 2nd operand because there are no V-bits to set. An immediate constant is always completely defined. Fixes bugzilla #305948. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12969 --- diff --git a/NEWS b/NEWS index 831a0604cb..acd5ad1b3f 100644 --- a/NEWS +++ b/NEWS @@ -45,6 +45,7 @@ m = merged into 3_8_BRANCH 305690 m [381] DRD reporting invalid semaphore when sem_trywait returns EAGAIN or sem_timedwait returns ETIMEDOUT 305926 m [381] Invalid alignment checks for some AVX instructions +305948 [390] ppc64: code generation for ShlD64 / ShrD64 asserts 306054 [390] s390x: Condition code computation for convert-to-int/logical 306310 [390] 3.8.0 release tarball missing some files n-i-bz m [381] shmat of a segment > 4Gb does not work diff --git a/docs/internals/3_8_BUGSTATUS.txt b/docs/internals/3_8_BUGSTATUS.txt index 2f81b5aa6b..33e1d933c2 100644 --- a/docs/internals/3_8_BUGSTATUS.txt +++ b/docs/internals/3_8_BUGSTATUS.txt @@ -91,8 +91,6 @@ n-i-bz exp-sgcheck asserts on gcc-4.6.2 generated Dwarf3 305728 Add support for AVX2 instructions -305948 ppc64: code generation for ShlD64 / ShrD64 asserts - 305957 m_debuginfo/d3basics.c:965 (vgModuleLocal_evaluate_GX): Assertion 'aMin == (Addr)0' failed. diff --git a/memcheck/tests/vbit-test/binary.c b/memcheck/tests/vbit-test/binary.c index 23eaaec163..78afc9bb4d 100644 --- a/memcheck/tests/vbit-test/binary.c +++ b/memcheck/tests/vbit-test/binary.c @@ -189,6 +189,10 @@ test_shift(const irop_t *op, test_data_t *data) } // 2nd (right) operand + + /* If the operand is an immediate value, there are no v-bits to set. */ + if (op->shift_amount_is_immediate) return; + num_input_bits = bitsof_irtype(opnds[1].type); for (i = 0; i < num_input_bits; ++i) { @@ -410,6 +414,11 @@ test_binary_op(const irop_t *op, test_data_t *data) that propagates to the output. Do this for all bits in each operand. */ for (i = 0; i < 2; ++i) { + + /* If this is a shift op that requires an immediate shift amount, + do not iterate the v-bits of the 2nd operand */ + if (i == 1 && op->shift_amount_is_immediate) break; + 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)); @@ -418,6 +427,11 @@ test_binary_op(const irop_t *op, test_data_t *data) won't crash. */ memset(&opnds[1].value, 0xff, sizeof opnds[1].value); + /* For immediate shift amounts choose a value of '1'. That should + not cause a problem. */ + if (op->shift_amount_is_immediate) + opnds[1].value.u8 = 1; + for (bitpos = 0; bitpos < num_input_bits; ++bitpos) { opnds[i].vbits = onehot_vbits(bitpos, bitsof_irtype(opnds[i].type)); diff --git a/memcheck/tests/vbit-test/irops.c b/memcheck/tests/vbit-test/irops.c index 24e15cdd5c..542338458f 100644 --- a/memcheck/tests/vbit-test/irops.c +++ b/memcheck/tests/vbit-test/irops.c @@ -9,7 +9,7 @@ /* The opcodes appear in the same order here as in libvex_ir.h That is not necessary but helpful when supporting a new architecture. */ -static const irop_t irops[] = { +static irop_t irops[] = { { DEFOP(Iop_Add8, UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0 }, { DEFOP(Iop_Add16, UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0 }, { DEFOP(Iop_Add32, UNDEF_LEFT), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1 }, @@ -479,10 +479,10 @@ static const irop_t irops[] = { { DEFOP(Iop_SubD128, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 }, { DEFOP(Iop_MulD128, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 }, { DEFOP(Iop_DivD128, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 }, - { DEFOP(Iop_ShlD64, UNDEF_SHL), .s390x = 0, .ppc64 = 0, .ppc32 = 0 }, // BZ #305948 - { DEFOP(Iop_ShrD64, UNDEF_SHR), .s390x = 0, .ppc64 = 0, .ppc32 = 0 }, // BZ #305948 - { DEFOP(Iop_ShlD128, UNDEF_SHL), .s390x = 0, .ppc64 = 0, .ppc32 = 0 }, // BZ #305948 - { DEFOP(Iop_ShrD128, UNDEF_SHR), .s390x = 0, .ppc64 = 0, .ppc32 = 0 }, // BZ #305948 + { DEFOP(Iop_ShlD64, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 }, + { DEFOP(Iop_ShrD64, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 }, + { DEFOP(Iop_ShlD128, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 }, + { DEFOP(Iop_ShrD128, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 }, { DEFOP(Iop_D32toD64, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 }, { DEFOP(Iop_D64toD128, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 }, { DEFOP(Iop_I64StoD128, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 }, @@ -859,13 +859,13 @@ static const irop_t irops[] = { /* Return a descriptor for OP, iff it exists and it is implemented for the current architecture. */ -const irop_t * +irop_t * get_irop(IROp op) { unsigned i; for (i = 0; i < sizeof irops / sizeof *irops; ++i) { - const irop_t *p = irops + i; + irop_t *p = irops + i; if (p->op == op) { #ifdef __s390x__ #define S390X_FEATURES "../../../tests/s390x_features" diff --git a/memcheck/tests/vbit-test/main.c b/memcheck/tests/vbit-test/main.c index c510f3c4a4..e9e2a26a42 100644 --- a/memcheck/tests/vbit-test/main.c +++ b/memcheck/tests/vbit-test/main.c @@ -50,6 +50,20 @@ new_test_data(const irop_t *op) int verbose = 0; + +/* Certain IROps require special handling. */ +static void +fixup_irops(void) +{ +#ifdef __powerpc__ + get_irop(Iop_ShlD64)->shift_amount_is_immediate = 1; + get_irop(Iop_ShrD64)->shift_amount_is_immediate = 1; + get_irop(Iop_ShlD128)->shift_amount_is_immediate = 1; + get_irop(Iop_ShrD128)->shift_amount_is_immediate = 1; +#endif +} + + int main(int argc, char *argv[]) { @@ -75,6 +89,8 @@ main(int argc, char *argv[]) setbuf(stdout, NULL); // make stdout unbuffered + fixup_irops(); // determine need for special handling + // Iterate over all primops IROp first = Iop_INVALID + 1; IROp last = Iop_LAST; diff --git a/memcheck/tests/vbit-test/valgrind.c b/memcheck/tests/vbit-test/valgrind.c index 976ae2c5cd..6073fcb27b 100644 --- a/memcheck/tests/vbit-test/valgrind.c +++ b/memcheck/tests/vbit-test/valgrind.c @@ -27,6 +27,8 @@ new_iricb(const irop_t *op, test_data_t *data) cb.num_operands = get_num_operands(op->op); + cb.shift_amount_is_immediate = op->shift_amount_is_immediate; + return cb; } diff --git a/memcheck/tests/vbit-test/vtest.h b/memcheck/tests/vbit-test/vtest.h index 2550c9c5e0..bb7b2fd692 100644 --- a/memcheck/tests/vbit-test/vtest.h +++ b/memcheck/tests/vbit-test/vtest.h @@ -63,6 +63,7 @@ typedef struct { IROp op; const char *name; undef_t undef_kind; + int shift_amount_is_immediate; // Indicate whether IROp can be tested on a particular architecture unsigned s390x : 1; unsigned amd64 : 1; @@ -95,7 +96,7 @@ typedef struct { /* Function prototypes */ -const irop_t *get_irop(IROp); +irop_t *get_irop(IROp); int is_floating_point_op_with_rounding_mode(IROp); int get_num_operands(IROp);