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
, },
146 static bool x86__ins_is_fused(struct arch
*arch
, const char *ins1
,
149 if (arch
->family
!= 6 || arch
->model
< 0x1e || strstr(ins2
, "jmp"))
152 if (arch
->model
== 0x1e) {
154 if ((strstr(ins1
, "cmp") && !strstr(ins1
, "xchg")) ||
155 strstr(ins1
, "test")) {
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")) {
174 static int x86__cpuid_parse(struct arch
*arch
, char *cpuid
)
176 unsigned int family
, model
, stepping
;
180 * cpuid = "GenuineIntel,family,model,stepping"
182 ret
= sscanf(cpuid
, "%*[^,],%u,%u,%u", &family
, &model
, &stepping
);
184 arch
->family
= family
;
192 static int x86__annotate_init(struct arch
*arch
, char *cpuid
)
196 if (arch
->initialized
)
200 if (x86__cpuid_parse(arch
, cpuid
))
201 err
= SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING
;
204 arch
->initialized
= true;