1  /* { dg-do compile { target x86_64-pc-linux-gnu } } */
       2  /* { dg-require-effective-target lp64 } */
       3  /* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
       4  /* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */
       5  
       6  /* Adapted/reduced from linux kernel (GPL-2.0).  */
       7  
       8  register unsigned long current_stack_pointer asm("rsp");
       9  
      10  struct pv_cpu_ops {
      11    /* snip */
      12    void (*cpuid)(unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
      13                  unsigned int *edx);
      14    /* snip */
      15  };
      16  struct paravirt_patch_template {
      17    struct pv_cpu_ops cpu;
      18    /* snip */
      19  };
      20  extern struct paravirt_patch_template pv_ops;
      21  
      22  /* snip */
      23  static void cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
      24  		  unsigned int *edx) {
      25    unsigned long __edi = __edi, __esi = __esi, __edx = __edx, __ecx = __ecx,
      26                  __eax = __eax;
      27    asm volatile(
      28        "771:\n\t"
      29        "999:\n\t"
      30        ".pushsection .discard.retpoline_safe\n\t"
      31        " "
      32        ".quad"
      33        " "
      34        " 999b\n\t"
      35        ".popsection\n\t"
      36        "call *%c[paravirt_opptr];"
      37        "\n"
      38        "772:\n"
      39        ".pushsection .parainstructions,\"a\"\n"
      40        " "
      41        ".balign 8"
      42        " "
      43        "\n"
      44        " "
      45        ".quad"
      46        " "
      47        " 771b\n"
      48        "  .byte "
      49        "%c[paravirt_typenum]"
      50        "\n"
      51        "  .byte 772b-771b\n"
      52        "  .short "
      53        "%c[paravirt_clobber]"
      54        "\n"
      55        ".popsection\n"
      56        : "=D"(__edi), "=S"(__esi), "=d"(__edx), "=c"(__ecx),
      57          "+r"(current_stack_pointer)
      58        : [ paravirt_typenum ] "i"(
      59              (__builtin_offsetof(struct paravirt_patch_template, cpu.cpuid) /
      60               sizeof(void *))),
      61          [ paravirt_opptr ] "i"(&(pv_ops.cpu.cpuid)),
      62          [ paravirt_clobber ] "i"(((1 << 9) - 1)), "D"((unsigned long)(eax)),
      63          "S"((unsigned long)(ebx)), "d"((unsigned long)(ecx)),
      64          "c"((unsigned long)(edx))
      65        : "memory", "cc", "rax", "r8", "r9", "r10", "r11");
      66  }
      67  
      68  extern void check_init_int(int v);
      69  
      70  void test(unsigned int op) {
      71    unsigned int eax, ebx, ecx, edx;
      72  
      73    eax = op;
      74    ecx = 0;
      75    cpuid(&eax, &ebx, &ecx, &edx);
      76  
      77    check_init_int(eax);
      78    check_init_int(ebx); /* { dg-bogus "use of uninitialized value 'ebx'" } */
      79    check_init_int(ecx);
      80    check_init_int(edx); /* { dg-bogus "use of uninitialized value 'edx'" } */
      81  }