|
From: <sv...@va...> - 2007-03-12 02:10:24
|
Author: sewardj
Date: 2007-03-12 02:10:23 +0000 (Mon, 12 Mar 2007)
New Revision: 6645
Log:
Add a test for vex ppc64 code generation bug fixed by vex r1739
(When generating 64-bit code, ensure that any addresses used in 4 or 8
byte loads or stores of the form reg+imm have the lowest 2 bits of imm
set to zero, so that they can safely be used in ld/ldu/lda/std/stdu
instructions.)
Added:
trunk/none/tests/ppc64/std_reg_imm.c
trunk/none/tests/ppc64/std_reg_imm.stderr.exp
trunk/none/tests/ppc64/std_reg_imm.stdout.exp
trunk/none/tests/ppc64/std_reg_imm.vgtest
Modified:
trunk/none/tests/ppc64/Makefile.am
Modified: trunk/none/tests/ppc64/Makefile.am
===================================================================
--- trunk/none/tests/ppc64/Makefile.am 2007-03-12 01:29:31 UTC (rev 6644)
+++ trunk/none/tests/ppc64/Makefile.am 2007-03-12 02:10:23 UTC (rev 6645)
@@ -6,11 +6,12 @@
jm-fp.stderr.exp jm-fp.stdout.exp jm-fp.vgtest \
jm-vmx.stderr.exp jm-vmx.stdout.exp jm-vmx.vgtest \
lsw.stderr.exp lsw.stdout.exp lsw.vgtest \
+ std_reg_imm.vgtest std_reg_imm.stderr.exp std_reg_imm.stdout.exp \
round.stderr.exp round.stdout.exp round.vgtest \
twi_tdi.stderr.exp twi_tdi.stdout.exp twi_tdi.vgtest
check_PROGRAMS = \
- jm-insns lsw round twi_tdi
+ jm-insns lsw round std_reg_imm twi_tdi
AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -g -I$(top_srcdir)/include \
@FLAG_M64@
Added: trunk/none/tests/ppc64/std_reg_imm.c
===================================================================
--- trunk/none/tests/ppc64/std_reg_imm.c (rev 0)
+++ trunk/none/tests/ppc64/std_reg_imm.c 2007-03-12 02:10:23 UTC (rev 6645)
@@ -0,0 +1,79 @@
+
+/*
+This is a regression test for the following problem, noticed by
+Greg Parker:
+
+vex ppc64 generates bad code for instruction sequences like this:
+
+ li r0, 2
+ stdx r3, r1, r0
+
+gcc emits code like this when manipulating packed structures
+with 8-byte fields on 2-byte boundaries.
+
+First, vex's optimizer substitutes a constant 0x2 for r0:
+
+ ------ IMark(0x100000F34, 4) ------
+ PUT(1024) = 0x100000F34:I64
+ t3 = GET:I64(24)
+ t14 = GET:I64(8)
+ t13 = Add64(t14,0x2:I64)
+ STbe(t13) = t3
+
+Then instruction selection chooses `std` with an index not divisible by 4:
+
+ -- STbe(Add64(GET:I64(8),0x2:I64)) = GET:I64(24)
+ ldz %vR22,8(%r31)
+ ldz %vR23,24(%r31)
+ std %vR23,2(%vR22)
+
+Finally, the assembler silently strips the index&3 part,
+because `std` can't encode that:
+
+ std %r6,2(%r5)
+ F8 C5 00 00
+
+...but 0xF8C50000 is `std r6, 0(r5)`, which writes to the wrong address.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+typedef
+struct __attribute__ ((__packed__)) {
+ char before[2];
+ unsigned long long int w64;
+ char after[6];
+}
+T;
+
+void foo (T* t, unsigned long long int w)
+{
+ __asm__ __volatile__(
+ "stdx %0,%1,%2"
+ : : "b"(w), "b"(t), "b"(2) : "memory"
+ );
+}
+
+int main ( void )
+{
+ T* t;
+ unsigned char* p;
+ int i;
+ assert(sizeof(T) == 16);
+ t = calloc(sizeof(T),1);
+ assert(t);
+ /* check t is 8-aligned. This causes the write done by 'foo' to be
+ misaligned by 2 as desired, triggering the bug. */
+ assert(0 == (((unsigned long)t) & 7));
+ foo(t, 0x1122334455667788);
+ p = (unsigned char*)t;
+ for (i = 0; i < 16; i++)
+ if (p[i] == 0)
+ printf("..");
+ else
+ printf("%02x", (int)p[i]);
+ printf("\n");
+ return 0;
+}
Added: trunk/none/tests/ppc64/std_reg_imm.stderr.exp
===================================================================
Added: trunk/none/tests/ppc64/std_reg_imm.stdout.exp
===================================================================
--- trunk/none/tests/ppc64/std_reg_imm.stdout.exp (rev 0)
+++ trunk/none/tests/ppc64/std_reg_imm.stdout.exp 2007-03-12 02:10:23 UTC (rev 6645)
@@ -0,0 +1 @@
+....1122334455667788............
Added: trunk/none/tests/ppc64/std_reg_imm.vgtest
===================================================================
--- trunk/none/tests/ppc64/std_reg_imm.vgtest (rev 0)
+++ trunk/none/tests/ppc64/std_reg_imm.vgtest 2007-03-12 02:10:23 UTC (rev 6645)
@@ -0,0 +1,2 @@
+prog: std_reg_imm
+vgopts: -q
|