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