Linux Perf
instructions.c
Go to the documentation of this file.
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 }
static struct ins_ops jump_ops
Definition: annotate.c:82
static struct ins x86__instructions[]
Definition: instructions.c:2
int int err
Definition: 5sec.c:44
Definition: annotate.h:17
const char * name
Definition: annotate.h:18
unsigned int family
Definition: annotate.c:70
static int x86__annotate_init(struct arch *arch, char *cpuid)
Definition: instructions.c:192
static int x86__cpuid_parse(struct arch *arch, char *cpuid)
Definition: instructions.c:174
static struct ins_ops lock_ops
Definition: annotate.c:85
static struct ins_ops mov_ops
Definition: annotate.c:83
static bool x86__ins_is_fused(struct arch *arch, const char *ins1, const char *ins2)
Definition: instructions.c:146
unsigned int model
Definition: annotate.c:69
static struct ins_ops nop_ops
Definition: annotate.c:84
static struct ins_ops ret_ops
Definition: annotate.c:86
bool initialized
Definition: annotate.c:67
Definition: annotate.c:60
static void cpuid(unsigned int op, unsigned int *a, unsigned int *b, unsigned int *c, unsigned int *d)
Definition: header.c:11
static struct ins_ops call_ops
Definition: annotate.c:80
static struct ins_ops dec_ops
Definition: annotate.c:81