File: asm-x86-linux-cpuid-paravirt-1.c

package info (click to toggle)
gcc-arm-none-eabi 15%3A14.2.rel1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,099,328 kB
  • sloc: cpp: 3,627,108; ansic: 2,571,498; ada: 834,230; f90: 235,082; makefile: 79,231; asm: 74,984; xml: 51,692; exp: 39,736; sh: 33,298; objc: 15,629; python: 15,069; fortran: 14,429; pascal: 7,003; awk: 5,070; perl: 3,106; ml: 285; lisp: 253; lex: 204; haskell: 135
file content (81 lines) | stat: -rw-r--r-- 2,257 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/* { dg-do compile { target x86_64-pc-linux-gnu } } */
/* { dg-require-effective-target lp64 } */
/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */

/* Adapted/reduced from linux kernel (GPL-2.0).  */

register unsigned long current_stack_pointer asm("rsp");

struct pv_cpu_ops {
  /* snip */
  void (*cpuid)(unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
                unsigned int *edx);
  /* snip */
};
struct paravirt_patch_template {
  struct pv_cpu_ops cpu;
  /* snip */
};
extern struct paravirt_patch_template pv_ops;

/* snip */
static void cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
		  unsigned int *edx) {
  unsigned long __edi = __edi, __esi = __esi, __edx = __edx, __ecx = __ecx,
                __eax = __eax;
  asm volatile(
      "771:\n\t"
      "999:\n\t"
      ".pushsection .discard.retpoline_safe\n\t"
      " "
      ".quad"
      " "
      " 999b\n\t"
      ".popsection\n\t"
      "call *%c[paravirt_opptr];"
      "\n"
      "772:\n"
      ".pushsection .parainstructions,\"a\"\n"
      " "
      ".balign 8"
      " "
      "\n"
      " "
      ".quad"
      " "
      " 771b\n"
      "  .byte "
      "%c[paravirt_typenum]"
      "\n"
      "  .byte 772b-771b\n"
      "  .short "
      "%c[paravirt_clobber]"
      "\n"
      ".popsection\n"
      : "=D"(__edi), "=S"(__esi), "=d"(__edx), "=c"(__ecx),
        "+r"(current_stack_pointer)
      : [ paravirt_typenum ] "i"(
            (__builtin_offsetof(struct paravirt_patch_template, cpu.cpuid) /
             sizeof(void *))),
        [ paravirt_opptr ] "i"(&(pv_ops.cpu.cpuid)),
        [ paravirt_clobber ] "i"(((1 << 9) - 1)), "D"((unsigned long)(eax)),
        "S"((unsigned long)(ebx)), "d"((unsigned long)(ecx)),
        "c"((unsigned long)(edx))
      : "memory", "cc", "rax", "r8", "r9", "r10", "r11");
}

extern void check_init_int(int v);

void test(unsigned int op) {
  unsigned int eax, ebx, ecx, edx;

  eax = op;
  ecx = 0;
  cpuid(&eax, &ebx, &ecx, &edx);

  check_init_int(eax);
  check_init_int(ebx); /* { dg-bogus "use of uninitialized value 'ebx'" } */
  check_init_int(ecx);
  check_init_int(edx); /* { dg-bogus "use of uninitialized value 'edx'" } */
}