1/* Test for reload failing to eliminate from argp to sp. */ 2/* { dg-do run } */ 3/* { dg-require-effective-target ilp32 } */ 4/* { dg-require-effective-target nonpic } */ 5/* { dg-options "-O2 -fomit-frame-pointer" } */ 6 7static int ustrsize (const char *s); 8static int (*ucwidth) (int c); 9static int (*ugetxc) (const char **s); 10static int (*usetc) (char *s, int c); 11 12char *ustrzcat(char *dest, int size, const char *src) 13{ 14 int pos = ustrsize(dest); 15 int c; 16 17 size -= pos + ucwidth(0); 18 19 while ((c = ugetxc(&src)) != 0) { 20 size -= ucwidth(c); 21 if (size < 0) 22 break; 23 24 pos += usetc(dest+pos, c); 25 } 26 27 usetc(dest+pos, 0); 28 29 return dest; 30} 31 32static int __attribute__((noinline)) 33ustrsize (const char *s) 34{ 35 return 0; 36} 37 38static int 39ucwidth_ (int c) 40{ 41 return 1; 42} 43 44static int 45ugetxc_ (const char **s) 46{ 47 return '\0'; 48} 49 50static int 51usetc_ (char *s, int c) 52{ 53 return 1; 54} 55 56int 57main() 58{ 59 ucwidth = ucwidth_; 60 ugetxc = ugetxc_; 61 usetc = usetc_; 62 63 /* ??? It is impossible to explicitly modify the hard frame pointer. 64 This will run afoul of code in flow.c that declines to mark regs 65 in eliminate_regs in regs_ever_used. Apparently, we have to wait 66 for reload to decide that it won't need a frame pointer before a 67 variable can be allocated to %ebp. 68 69 So save, restore, and clobber %ebp by hand. */ 70 71 asm ("pushl %%ebp\n\t" 72 "movl $-1, %%ebp\n\t" 73 "pushl $0\n\t" 74 "pushl $0\n\t" 75 "pushl $0\n\t" 76 "call %P0\n\t" 77 "addl $12, %%esp\n\t" 78 "popl %%ebp" 79 : : "i"(ustrzcat) : "memory" ); 80 81 return 0; 82} 83