GNU Linux-libre 4.19.295-gnu1
[releases.git] / tools / perf / arch / x86 / annotate / instructions.c
1 // SPDX-License-Identifier: GPL-2.0
2 static struct ins x86__instructions[] = {
3         { .name = "adc",        .ops = &mov_ops,  },
4         { .name = "adcb",       .ops = &mov_ops,  },
5         { .name = "adcl",       .ops = &mov_ops,  },
6         { .name = "add",        .ops = &mov_ops,  },
7         { .name = "addl",       .ops = &mov_ops,  },
8         { .name = "addq",       .ops = &mov_ops,  },
9         { .name = "addsd",      .ops = &mov_ops,  },
10         { .name = "addw",       .ops = &mov_ops,  },
11         { .name = "and",        .ops = &mov_ops,  },
12         { .name = "andb",       .ops = &mov_ops,  },
13         { .name = "andl",       .ops = &mov_ops,  },
14         { .name = "andpd",      .ops = &mov_ops,  },
15         { .name = "andps",      .ops = &mov_ops,  },
16         { .name = "andq",       .ops = &mov_ops,  },
17         { .name = "andw",       .ops = &mov_ops,  },
18         { .name = "bsr",        .ops = &mov_ops,  },
19         { .name = "bt",         .ops = &mov_ops,  },
20         { .name = "btr",        .ops = &mov_ops,  },
21         { .name = "bts",        .ops = &mov_ops,  },
22         { .name = "btsq",       .ops = &mov_ops,  },
23         { .name = "call",       .ops = &call_ops, },
24         { .name = "callq",      .ops = &call_ops, },
25         { .name = "cmovbe",     .ops = &mov_ops,  },
26         { .name = "cmove",      .ops = &mov_ops,  },
27         { .name = "cmovae",     .ops = &mov_ops,  },
28         { .name = "cmp",        .ops = &mov_ops,  },
29         { .name = "cmpb",       .ops = &mov_ops,  },
30         { .name = "cmpl",       .ops = &mov_ops,  },
31         { .name = "cmpq",       .ops = &mov_ops,  },
32         { .name = "cmpw",       .ops = &mov_ops,  },
33         { .name = "cmpxch",     .ops = &mov_ops,  },
34         { .name = "cmpxchg",    .ops = &mov_ops,  },
35         { .name = "cs",         .ops = &mov_ops,  },
36         { .name = "dec",        .ops = &dec_ops,  },
37         { .name = "decl",       .ops = &dec_ops,  },
38         { .name = "divsd",      .ops = &mov_ops,  },
39         { .name = "divss",      .ops = &mov_ops,  },
40         { .name = "gs",         .ops = &mov_ops,  },
41         { .name = "imul",       .ops = &mov_ops,  },
42         { .name = "inc",        .ops = &dec_ops,  },
43         { .name = "incl",       .ops = &dec_ops,  },
44         { .name = "ja",         .ops = &jump_ops, },
45         { .name = "jae",        .ops = &jump_ops, },
46         { .name = "jb",         .ops = &jump_ops, },
47         { .name = "jbe",        .ops = &jump_ops, },
48         { .name = "jc",         .ops = &jump_ops, },
49         { .name = "jcxz",       .ops = &jump_ops, },
50         { .name = "je",         .ops = &jump_ops, },
51         { .name = "jecxz",      .ops = &jump_ops, },
52         { .name = "jg",         .ops = &jump_ops, },
53         { .name = "jge",        .ops = &jump_ops, },
54         { .name = "jl",         .ops = &jump_ops, },
55         { .name = "jle",        .ops = &jump_ops, },
56         { .name = "jmp",        .ops = &jump_ops, },
57         { .name = "jmpq",       .ops = &jump_ops, },
58         { .name = "jna",        .ops = &jump_ops, },
59         { .name = "jnae",       .ops = &jump_ops, },
60         { .name = "jnb",        .ops = &jump_ops, },
61         { .name = "jnbe",       .ops = &jump_ops, },
62         { .name = "jnc",        .ops = &jump_ops, },
63         { .name = "jne",        .ops = &jump_ops, },
64         { .name = "jng",        .ops = &jump_ops, },
65         { .name = "jnge",       .ops = &jump_ops, },
66         { .name = "jnl",        .ops = &jump_ops, },
67         { .name = "jnle",       .ops = &jump_ops, },
68         { .name = "jno",        .ops = &jump_ops, },
69         { .name = "jnp",        .ops = &jump_ops, },
70         { .name = "jns",        .ops = &jump_ops, },
71         { .name = "jnz",        .ops = &jump_ops, },
72         { .name = "jo",         .ops = &jump_ops, },
73         { .name = "jp",         .ops = &jump_ops, },
74         { .name = "jpe",        .ops = &jump_ops, },
75         { .name = "jpo",        .ops = &jump_ops, },
76         { .name = "jrcxz",      .ops = &jump_ops, },
77         { .name = "js",         .ops = &jump_ops, },
78         { .name = "jz",         .ops = &jump_ops, },
79         { .name = "lea",        .ops = &mov_ops,  },
80         { .name = "lock",       .ops = &lock_ops, },
81         { .name = "mov",        .ops = &mov_ops,  },
82         { .name = "movapd",     .ops = &mov_ops,  },
83         { .name = "movaps",     .ops = &mov_ops,  },
84         { .name = "movb",       .ops = &mov_ops,  },
85         { .name = "movdqa",     .ops = &mov_ops,  },
86         { .name = "movdqu",     .ops = &mov_ops,  },
87         { .name = "movl",       .ops = &mov_ops,  },
88         { .name = "movq",       .ops = &mov_ops,  },
89         { .name = "movsd",      .ops = &mov_ops,  },
90         { .name = "movslq",     .ops = &mov_ops,  },
91         { .name = "movss",      .ops = &mov_ops,  },
92         { .name = "movupd",     .ops = &mov_ops,  },
93         { .name = "movups",     .ops = &mov_ops,  },
94         { .name = "movw",       .ops = &mov_ops,  },
95         { .name = "movzbl",     .ops = &mov_ops,  },
96         { .name = "movzwl",     .ops = &mov_ops,  },
97         { .name = "mulsd",      .ops = &mov_ops,  },
98         { .name = "mulss",      .ops = &mov_ops,  },
99         { .name = "nop",        .ops = &nop_ops,  },
100         { .name = "nopl",       .ops = &nop_ops,  },
101         { .name = "nopw",       .ops = &nop_ops,  },
102         { .name = "or",         .ops = &mov_ops,  },
103         { .name = "orb",        .ops = &mov_ops,  },
104         { .name = "orl",        .ops = &mov_ops,  },
105         { .name = "orps",       .ops = &mov_ops,  },
106         { .name = "orq",        .ops = &mov_ops,  },
107         { .name = "pand",       .ops = &mov_ops,  },
108         { .name = "paddq",      .ops = &mov_ops,  },
109         { .name = "pcmpeqb",    .ops = &mov_ops,  },
110         { .name = "por",        .ops = &mov_ops,  },
111         { .name = "rclb",       .ops = &mov_ops,  },
112         { .name = "rcll",       .ops = &mov_ops,  },
113         { .name = "retq",       .ops = &ret_ops,  },
114         { .name = "sbb",        .ops = &mov_ops,  },
115         { .name = "sbbl",       .ops = &mov_ops,  },
116         { .name = "sete",       .ops = &mov_ops,  },
117         { .name = "sub",        .ops = &mov_ops,  },
118         { .name = "subl",       .ops = &mov_ops,  },
119         { .name = "subq",       .ops = &mov_ops,  },
120         { .name = "subsd",      .ops = &mov_ops,  },
121         { .name = "subw",       .ops = &mov_ops,  },
122         { .name = "test",       .ops = &mov_ops,  },
123         { .name = "testb",      .ops = &mov_ops,  },
124         { .name = "testl",      .ops = &mov_ops,  },
125         { .name = "ucomisd",    .ops = &mov_ops,  },
126         { .name = "ucomiss",    .ops = &mov_ops,  },
127         { .name = "vaddsd",     .ops = &mov_ops,  },
128         { .name = "vandpd",     .ops = &mov_ops,  },
129         { .name = "vmovdqa",    .ops = &mov_ops,  },
130         { .name = "vmovq",      .ops = &mov_ops,  },
131         { .name = "vmovsd",     .ops = &mov_ops,  },
132         { .name = "vmulsd",     .ops = &mov_ops,  },
133         { .name = "vorpd",      .ops = &mov_ops,  },
134         { .name = "vsubsd",     .ops = &mov_ops,  },
135         { .name = "vucomisd",   .ops = &mov_ops,  },
136         { .name = "xadd",       .ops = &mov_ops,  },
137         { .name = "xbeginl",    .ops = &jump_ops, },
138         { .name = "xbeginq",    .ops = &jump_ops, },
139         { .name = "xchg",       .ops = &mov_ops,  },
140         { .name = "xor",        .ops = &mov_ops, },
141         { .name = "xorb",       .ops = &mov_ops, },
142         { .name = "xorpd",      .ops = &mov_ops, },
143         { .name = "xorps",      .ops = &mov_ops, },
144 };
145
146 static bool x86__ins_is_fused(struct arch *arch, const char *ins1,
147                               const char *ins2)
148 {
149         if (arch->family != 6 || arch->model < 0x1e || strstr(ins2, "jmp"))
150                 return false;
151
152         if (arch->model == 0x1e) {
153                 /* Nehalem */
154                 if ((strstr(ins1, "cmp") && !strstr(ins1, "xchg")) ||
155                      strstr(ins1, "test")) {
156                         return true;
157                 }
158         } else {
159                 /* Newer platform */
160                 if ((strstr(ins1, "cmp") && !strstr(ins1, "xchg")) ||
161                      strstr(ins1, "test") ||
162                      strstr(ins1, "add") ||
163                      strstr(ins1, "sub") ||
164                      strstr(ins1, "and") ||
165                      strstr(ins1, "inc") ||
166                      strstr(ins1, "dec")) {
167                         return true;
168                 }
169         }
170
171         return false;
172 }
173
174 static int x86__cpuid_parse(struct arch *arch, char *cpuid)
175 {
176         unsigned int family, model, stepping;
177         int ret;
178
179         /*
180          * cpuid = "GenuineIntel,family,model,stepping"
181          */
182         ret = sscanf(cpuid, "%*[^,],%u,%u,%u", &family, &model, &stepping);
183         if (ret == 3) {
184                 arch->family = family;
185                 arch->model = model;
186                 return 0;
187         }
188
189         return -1;
190 }
191
192 static int x86__annotate_init(struct arch *arch, char *cpuid)
193 {
194         int err = 0;
195
196         if (arch->initialized)
197                 return 0;
198
199         if (cpuid)
200                 err = x86__cpuid_parse(arch, cpuid);
201
202         arch->initialized = true;
203         return err;
204 }