1 use crate::cdsl::settings::{PredicateNode, SettingGroup, SettingGroupBuilder};
2
define(shared: &SettingGroup) -> SettingGroup3 pub(crate) fn define(shared: &SettingGroup) -> SettingGroup {
4 let mut settings = SettingGroupBuilder::new("x86");
5
6 // CPUID.01H:ECX
7 let has_sse3 = settings.add_bool(
8 "has_sse3",
9 "Has support for SSE3.",
10 "SSE3: CPUID.01H:ECX.SSE3[bit 0]",
11 false,
12 );
13 let has_ssse3 = settings.add_bool(
14 "has_ssse3",
15 "Has support for SSSE3.",
16 "SSSE3: CPUID.01H:ECX.SSSE3[bit 9]",
17 false,
18 );
19 let has_sse41 = settings.add_bool(
20 "has_sse41",
21 "Has support for SSE4.1.",
22 "SSE4.1: CPUID.01H:ECX.SSE4_1[bit 19]",
23 false,
24 );
25 let has_sse42 = settings.add_bool(
26 "has_sse42",
27 "Has support for SSE4.2.",
28 "SSE4.2: CPUID.01H:ECX.SSE4_2[bit 20]",
29 false,
30 );
31 let has_avx = settings.add_bool(
32 "has_avx",
33 "Has support for AVX.",
34 "AVX: CPUID.01H:ECX.AVX[bit 28]",
35 false,
36 );
37 let has_avx2 = settings.add_bool(
38 "has_avx2",
39 "Has support for AVX2.",
40 "AVX2: CPUID.07H:EBX.AVX2[bit 5]",
41 false,
42 );
43 let has_avx512dq = settings.add_bool(
44 "has_avx512dq",
45 "Has support for AVX512DQ.",
46 "AVX512DQ: CPUID.07H:EBX.AVX512DQ[bit 17]",
47 false,
48 );
49 let has_avx512vl = settings.add_bool(
50 "has_avx512vl",
51 "Has support for AVX512VL.",
52 "AVX512VL: CPUID.07H:EBX.AVX512VL[bit 31]",
53 false,
54 );
55 let has_avx512f = settings.add_bool(
56 "has_avx512f",
57 "Has support for AVX512F.",
58 "AVX512F: CPUID.07H:EBX.AVX512F[bit 16]",
59 false,
60 );
61 let has_popcnt = settings.add_bool(
62 "has_popcnt",
63 "Has support for POPCNT.",
64 "POPCNT: CPUID.01H:ECX.POPCNT[bit 23]",
65 false,
66 );
67
68 // CPUID.(EAX=07H, ECX=0H):EBX
69 let has_bmi1 = settings.add_bool(
70 "has_bmi1",
71 "Has support for BMI1.",
72 "BMI1: CPUID.(EAX=07H, ECX=0H):EBX.BMI1[bit 3]",
73 false,
74 );
75 let has_bmi2 = settings.add_bool(
76 "has_bmi2",
77 "Has support for BMI2.",
78 "BMI2: CPUID.(EAX=07H, ECX=0H):EBX.BMI2[bit 8]",
79 false,
80 );
81
82 // CPUID.EAX=80000001H:ECX
83 let has_lzcnt = settings.add_bool(
84 "has_lzcnt",
85 "Has support for LZCNT.",
86 "LZCNT: CPUID.EAX=80000001H:ECX.LZCNT[bit 5]",
87 false,
88 );
89
90 let shared_enable_simd = shared.get_bool("enable_simd");
91
92 settings.add_predicate("use_ssse3", predicate!(has_ssse3));
93 settings.add_predicate("use_sse41", predicate!(has_sse41));
94 settings.add_predicate("use_sse42", predicate!(has_sse41 && has_sse42));
95
96 settings.add_predicate(
97 "use_ssse3_simd",
98 predicate!(shared_enable_simd && has_ssse3),
99 );
100 settings.add_predicate(
101 "use_sse41_simd",
102 predicate!(shared_enable_simd && has_sse41),
103 );
104 settings.add_predicate(
105 "use_sse42_simd",
106 predicate!(shared_enable_simd && has_sse41 && has_sse42),
107 );
108
109 settings.add_predicate("use_avx_simd", predicate!(shared_enable_simd && has_avx));
110 settings.add_predicate("use_avx2_simd", predicate!(shared_enable_simd && has_avx2));
111 settings.add_predicate(
112 "use_avx512dq_simd",
113 predicate!(shared_enable_simd && has_avx512dq),
114 );
115 settings.add_predicate(
116 "use_avx512vl_simd",
117 predicate!(shared_enable_simd && has_avx512vl),
118 );
119 settings.add_predicate(
120 "use_avx512f_simd",
121 predicate!(shared_enable_simd && has_avx512f),
122 );
123
124 settings.add_predicate("use_popcnt", predicate!(has_popcnt && has_sse42));
125 settings.add_predicate("use_bmi1", predicate!(has_bmi1));
126 settings.add_predicate("use_lzcnt", predicate!(has_lzcnt));
127
128 // Some shared boolean values are used in x86 instruction predicates, so we need to group them
129 // in the same TargetIsa, for compatibility with code generated by meta-python.
130 // TODO Once all the meta generation code has been migrated from Python to Rust, we can put it
131 // back in the shared SettingGroup, and use it in x86 instruction predicates.
132
133 let is_pic = shared.get_bool("is_pic");
134 let emit_all_ones_funcaddrs = shared.get_bool("emit_all_ones_funcaddrs");
135 settings.add_predicate("is_pic", predicate!(is_pic));
136 settings.add_predicate("not_is_pic", predicate!(!is_pic));
137 settings.add_predicate(
138 "all_ones_funcaddrs_and_not_is_pic",
139 predicate!(emit_all_ones_funcaddrs && !is_pic),
140 );
141 settings.add_predicate(
142 "not_all_ones_funcaddrs_and_not_is_pic",
143 predicate!(!emit_all_ones_funcaddrs && !is_pic),
144 );
145
146 // Presets corresponding to x86 CPUs.
147
148 settings.add_preset(
149 "baseline",
150 "A baseline preset with no extensions enabled.",
151 preset!(),
152 );
153 let nehalem = settings.add_preset(
154 "nehalem",
155 "Nehalem microarchitecture.",
156 preset!(has_sse3 && has_ssse3 && has_sse41 && has_sse42 && has_popcnt),
157 );
158 let haswell = settings.add_preset(
159 "haswell",
160 "Haswell microarchitecture.",
161 preset!(nehalem && has_bmi1 && has_bmi2 && has_lzcnt),
162 );
163 let broadwell = settings.add_preset(
164 "broadwell",
165 "Broadwell microarchitecture.",
166 preset!(haswell),
167 );
168 let skylake = settings.add_preset("skylake", "Skylake microarchitecture.", preset!(broadwell));
169 let cannonlake = settings.add_preset(
170 "cannonlake",
171 "Canon Lake microarchitecture.",
172 preset!(skylake),
173 );
174 settings.add_preset(
175 "icelake",
176 "Ice Lake microarchitecture.",
177 preset!(cannonlake),
178 );
179 settings.add_preset(
180 "znver1",
181 "Zen (first generation) microarchitecture.",
182 preset!(
183 has_sse3
184 && has_ssse3
185 && has_sse41
186 && has_sse42
187 && has_popcnt
188 && has_bmi1
189 && has_bmi2
190 && has_lzcnt
191 ),
192 );
193
194 settings.build()
195 }
196