1  /* Test for reload failing to eliminate from argp to sp.  */
       2  /* { dg-do run } */
       3  /* { dg-require-effective-target ia32 } */
       4  /* { dg-require-effective-target nonpic } */
       5  /* { dg-options "-O2 -fomit-frame-pointer" } */
       6  
       7  static int ustrsize (const char *s);
       8  static int (*ucwidth) (int c);
       9  static int (*ugetxc) (const char **s);
      10  static int (*usetc) (char *s, int c);
      11  
      12  char *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  
      32  static int __attribute__((noinline))
      33  ustrsize (const char *s)
      34  {
      35    return 0;
      36  }
      37  
      38  static int
      39  ucwidth_ (int c)
      40  {
      41    return 1;
      42  }
      43  
      44  static int
      45  ugetxc_ (const char **s)
      46  {
      47    return '\0';
      48  }
      49  
      50  static int
      51  usetc_ (char *s, int c)
      52  {
      53    return 1;
      54  }
      55  
      56  int
      57  main()
      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  }