diff options
Diffstat (limited to 'gcc/testsuite/gcc.target/i386/20011119-1.c')
-rw-r--r-- | gcc/testsuite/gcc.target/i386/20011119-1.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.target/i386/20011119-1.c b/gcc/testsuite/gcc.target/i386/20011119-1.c new file mode 100644 index 00000000000..bbdf104d1c8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/20011119-1.c @@ -0,0 +1,82 @@ +/* Test for reload failing to eliminate from argp to sp. */ +/* { dg-do run { target i?86-*-* x86_64-*-* } } */ +/* { dg-require-effective-target ilp32 } */ +/* { dg-skip-if "" { "*-*-*" } { "-fpic" "-fPIC" } { "" } } */ +/* { dg-options "-O2 -fomit-frame-pointer" } */ + +static int ustrsize (const char *s); +static int (*ucwidth) (int c); +static int (*ugetxc) (const char **s); +static int (*usetc) (char *s, int c); + +char *ustrzcat(char *dest, int size, const char *src) +{ + int pos = ustrsize(dest); + int c; + + size -= pos + ucwidth(0); + + while ((c = ugetxc(&src)) != 0) { + size -= ucwidth(c); + if (size < 0) + break; + + pos += usetc(dest+pos, c); + } + + usetc(dest+pos, 0); + + return dest; +} + +static int __attribute__((noinline)) +ustrsize (const char *s) +{ + return 0; +} + +static int +ucwidth_ (int c) +{ + return 1; +} + +static int +ugetxc_ (const char **s) +{ + return '\0'; +} + +static int +usetc_ (char *s, int c) +{ + return 1; +} + +int +main() +{ + ucwidth = ucwidth_; + ugetxc = ugetxc_; + usetc = usetc_; + + /* ??? It is impossible to explicitly modify the hard frame pointer. + This will run afoul of code in flow.c that declines to mark regs + in eliminate_regs in regs_ever_used. Apparently, we have to wait + for reload to decide that it won't need a frame pointer before a + variable can be allocated to %ebp. + + So save, restore, and clobber %ebp by hand. */ + + asm ("pushl %%ebp\n\t" + "movl $-1, %%ebp\n\t" + "pushl $0\n\t" + "pushl $0\n\t" + "pushl $0\n\t" + "call %P0\n\t" + "addl $12, %%esp\n\t" + "popl %%ebp" + : : "i"(ustrzcat) : "memory" ); + + return 0; +} |