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 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/NEWS b/NEWS
index 831a060..acd5ad1 100644
--- a/NEWS
+++ b/NEWS
@@ -45,6 +45,7 @@
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 2f81b5a..33e1d93 100644
--- a/docs/internals/3_8_BUGSTATUS.txt
+++ b/docs/internals/3_8_BUGSTATUS.txt
@@ -91,8 +91,6 @@
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 23eaaec..78afc9b 100644
--- a/memcheck/tests/vbit-test/binary.c
+++ b/memcheck/tests/vbit-test/binary.c
@@ -189,6 +189,10 @@
}
// 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 @@
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 @@
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 24e15cd..5423384 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 @@
{ 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 @@
/* 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 c510f3c..e9e2a26 100644
--- a/memcheck/tests/vbit-test/main.c
+++ b/memcheck/tests/vbit-test/main.c
@@ -50,6 +50,20 @@
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 @@
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 976ae2c..6073fcb 100644
--- a/memcheck/tests/vbit-test/valgrind.c
+++ b/memcheck/tests/vbit-test/valgrind.c
@@ -27,6 +27,8 @@
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 2550c9c..bb7b2fd 100644
--- a/memcheck/tests/vbit-test/vtest.h
+++ b/memcheck/tests/vbit-test/vtest.h
@@ -63,6 +63,7 @@
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 @@
/* 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);