1  /* Test that the ms_hook_prologue attribute generates the correct code.  */
       2  
       3  /* { dg-do run } */
       4  /* { dg-require-effective-target ms_hook_prologue } */
       5  /* { dg-options "-O2 -fomit-frame-pointer" } */
       6  
       7  #include <stdio.h>
       8  
       9  int __attribute__ ((__ms_hook_prologue__)) foo ()
      10  {
      11    unsigned char *ptr = (unsigned char *) foo;
      12  
      13    /* The NOP mov must not be optimized away by optimizations.
      14       The push %ebp, mov %esp, %ebp must not be removed by
      15       -fomit-frame-pointer */
      16  #ifndef __x86_64__
      17    /* movl.s %edi, %edi */
      18    if(*ptr++ != 0x8b) return 1;
      19    if(*ptr++ != 0xff) return 1;
      20    /* push %ebp */
      21    if(*ptr++ != 0x55) return 1;
      22    /* movl.s %esp, %ebp */
      23    if(*ptr++ != 0x8b) return 1;
      24    if(*ptr++ != 0xec) return 1;
      25  #else
      26    /* leaq 0(%rsp), %rsp */
      27    if (*ptr++ != 0x48) return 1;
      28    if (*ptr++ != 0x8d) return 1;
      29    if (*ptr++ != 0xa4) return 1;
      30    if (*ptr++ != 0x24) return 1;
      31    if (ptr[0] != 0 || ptr[1] != 0 || ptr[2] != 0 || ptr[3] != 0)
      32      return 1;
      33  #endif
      34    return 0;
      35  }
      36  
      37  unsigned int __attribute__ ((noinline, __ms_hook_prologue__)) test_func()
      38  {
      39    static int value;
      40  
      41    if (value++) puts("");
      42  
      43    return 0;
      44  }
      45  
      46  int main ()
      47  {
      48    return foo() || test_func();
      49  }