1 use crate::cdsl::isa::TargetIsa; 2 use crate::cdsl::settings::{PredicateNode, SettingGroupBuilder}; 3 4 pub(crate) fn define() -> TargetIsa { 5 let mut settings = SettingGroupBuilder::new("x86"); 6 7 // CPUID.01H:ECX 8 let has_sse3 = settings.add_bool( 9 "has_sse3", 10 "Has support for SSE3.", 11 "SSE3: CPUID.01H:ECX.SSE3[bit 0]", 12 false, 13 ); 14 let has_ssse3 = settings.add_bool( 15 "has_ssse3", 16 "Has support for SSSE3.", 17 "SSSE3: CPUID.01H:ECX.SSSE3[bit 9]", 18 false, 19 ); 20 let has_cmpxchg16b = settings.add_bool( 21 "has_cmpxchg16b", 22 "Has support for CMPXCHG16b.", 23 "CMPXCHG16b: CPUID.01H:ECX.CMPXCHG16B[bit 13]", 24 false, 25 ); 26 let has_sse41 = settings.add_bool( 27 "has_sse41", 28 "Has support for SSE4.1.", 29 "SSE4.1: CPUID.01H:ECX.SSE4_1[bit 19]", 30 false, 31 ); 32 let has_sse42 = settings.add_bool( 33 "has_sse42", 34 "Has support for SSE4.2.", 35 "SSE4.2: CPUID.01H:ECX.SSE4_2[bit 20]", 36 false, 37 ); 38 let has_avx = settings.add_bool( 39 "has_avx", 40 "Has support for AVX.", 41 "AVX: CPUID.01H:ECX.AVX[bit 28]", 42 false, 43 ); 44 let has_avx2 = settings.add_bool( 45 "has_avx2", 46 "Has support for AVX2.", 47 "AVX2: CPUID.07H:EBX.AVX2[bit 5]", 48 false, 49 ); 50 let has_fma = settings.add_bool( 51 "has_fma", 52 "Has support for FMA.", 53 "FMA: CPUID.01H:ECX.FMA[bit 12]", 54 false, 55 ); 56 let has_avx512bitalg = settings.add_bool( 57 "has_avx512bitalg", 58 "Has support for AVX512BITALG.", 59 "AVX512BITALG: CPUID.07H:ECX.AVX512BITALG[bit 12]", 60 false, 61 ); 62 let has_avx512dq = settings.add_bool( 63 "has_avx512dq", 64 "Has support for AVX512DQ.", 65 "AVX512DQ: CPUID.07H:EBX.AVX512DQ[bit 17]", 66 false, 67 ); 68 let has_avx512vl = settings.add_bool( 69 "has_avx512vl", 70 "Has support for AVX512VL.", 71 "AVX512VL: CPUID.07H:EBX.AVX512VL[bit 31]", 72 false, 73 ); 74 let has_avx512vbmi = settings.add_bool( 75 "has_avx512vbmi", 76 "Has support for AVX512VMBI.", 77 "AVX512VBMI: CPUID.07H:ECX.AVX512VBMI[bit 1]", 78 false, 79 ); 80 let has_avx512f = settings.add_bool( 81 "has_avx512f", 82 "Has support for AVX512F.", 83 "AVX512F: CPUID.07H:EBX.AVX512F[bit 16]", 84 false, 85 ); 86 let has_popcnt = settings.add_bool( 87 "has_popcnt", 88 "Has support for POPCNT.", 89 "POPCNT: CPUID.01H:ECX.POPCNT[bit 23]", 90 false, 91 ); 92 93 // CPUID.(EAX=07H, ECX=0H):EBX 94 let has_bmi1 = settings.add_bool( 95 "has_bmi1", 96 "Has support for BMI1.", 97 "BMI1: CPUID.(EAX=07H, ECX=0H):EBX.BMI1[bit 3]", 98 false, 99 ); 100 let has_bmi2 = settings.add_bool( 101 "has_bmi2", 102 "Has support for BMI2.", 103 "BMI2: CPUID.(EAX=07H, ECX=0H):EBX.BMI2[bit 8]", 104 false, 105 ); 106 107 // CPUID.EAX=80000001H:ECX 108 let has_lzcnt = settings.add_bool( 109 "has_lzcnt", 110 "Has support for LZCNT.", 111 "LZCNT: CPUID.EAX=80000001H:ECX.LZCNT[bit 5]", 112 false, 113 ); 114 115 settings.add_predicate("use_cmpxchg16b", predicate!(has_cmpxchg16b)); 116 settings.add_predicate("use_sse3", predicate!(has_sse3)); 117 settings.add_predicate("use_ssse3", predicate!(has_ssse3)); 118 settings.add_predicate("use_sse41", predicate!(has_sse41)); 119 settings.add_predicate("use_sse42", predicate!(has_sse41 && has_sse42)); 120 settings.add_predicate("use_fma", predicate!(has_avx && has_fma)); 121 122 settings.add_predicate("use_avx", predicate!(has_avx)); 123 settings.add_predicate("use_avx2", predicate!(has_avx && has_avx2)); 124 settings.add_predicate("use_avx512bitalg", predicate!(has_avx512bitalg)); 125 settings.add_predicate("use_avx512dq", predicate!(has_avx512dq)); 126 settings.add_predicate("use_avx512vl", predicate!(has_avx512vl)); 127 settings.add_predicate("use_avx512vbmi", predicate!(has_avx512vbmi)); 128 settings.add_predicate("use_avx512f", predicate!(has_avx512f)); 129 130 settings.add_predicate("use_popcnt", predicate!(has_popcnt && has_sse42)); 131 settings.add_predicate("use_bmi1", predicate!(has_bmi1)); 132 settings.add_predicate("use_bmi2", predicate!(has_bmi2)); 133 settings.add_predicate("use_lzcnt", predicate!(has_lzcnt)); 134 135 let sse3 = settings.add_preset("sse3", "SSE3 and earlier.", preset!(has_sse3)); 136 let ssse3 = settings.add_preset("ssse3", "SSSE3 and earlier.", preset!(sse3 && has_ssse3)); 137 let sse41 = settings.add_preset("sse41", "SSE4.1 and earlier.", preset!(ssse3 && has_sse41)); 138 let sse42 = settings.add_preset("sse42", "SSE4.2 and earlier.", preset!(sse41 && has_sse42)); 139 140 // Presets corresponding to x86 CPUs. 141 // Features and architecture names are from LLVM's x86 presets: 142 // https://github.com/llvm/llvm-project/blob/d4493dd1ed58ac3f1eab0c4ca6e363e2b15bfd1c/llvm/lib/Target/X86/X86.td#L1300-L1643 143 settings.add_preset( 144 "baseline", 145 "A baseline preset with no extensions enabled.", 146 preset!(), 147 ); 148 149 // Intel CPUs 150 151 // Netburst 152 settings.add_preset( 153 "nocona", 154 "Nocona microarchitecture.", 155 preset!(sse3 && has_cmpxchg16b), 156 ); 157 158 // Intel Core 2 Solo/Duo 159 settings.add_preset( 160 "core2", 161 "Core 2 microarchitecture.", 162 preset!(sse3 && has_cmpxchg16b), 163 ); 164 settings.add_preset( 165 "penryn", 166 "Penryn microarchitecture.", 167 preset!(sse41 && has_cmpxchg16b), 168 ); 169 170 // Intel Atom CPUs 171 let atom = settings.add_preset( 172 "atom", 173 "Atom microarchitecture.", 174 preset!(ssse3 && has_cmpxchg16b), 175 ); 176 settings.add_preset("bonnell", "Bonnell microarchitecture.", preset!(atom)); 177 let silvermont = settings.add_preset( 178 "silvermont", 179 "Silvermont microarchitecture.", 180 preset!(atom && sse42 && has_popcnt), 181 ); 182 settings.add_preset("slm", "Silvermont microarchitecture.", preset!(silvermont)); 183 let goldmont = settings.add_preset( 184 "goldmont", 185 "Goldmont microarchitecture.", 186 preset!(silvermont), 187 ); 188 settings.add_preset( 189 "goldmont-plus", 190 "Goldmont Plus microarchitecture.", 191 preset!(goldmont), 192 ); 193 let tremont = settings.add_preset("tremont", "Tremont microarchitecture.", preset!(goldmont)); 194 195 let alderlake = settings.add_preset( 196 "alderlake", 197 "Alderlake microarchitecture.", 198 preset!(tremont && has_bmi1 && has_bmi2 && has_lzcnt && has_fma), 199 ); 200 let sierra_forest = settings.add_preset( 201 "sierraforest", 202 "Sierra Forest microarchitecture.", 203 preset!(alderlake), 204 ); 205 settings.add_preset( 206 "grandridge", 207 "Grandridge microarchitecture.", 208 preset!(sierra_forest), 209 ); 210 let nehalem = settings.add_preset( 211 "nehalem", 212 "Nehalem microarchitecture.", 213 preset!(sse42 && has_popcnt && has_cmpxchg16b), 214 ); 215 settings.add_preset("corei7", "Core i7 microarchitecture.", preset!(nehalem)); 216 let westmere = settings.add_preset("westmere", "Westmere microarchitecture.", preset!(nehalem)); 217 let sandy_bridge = settings.add_preset( 218 "sandybridge", 219 "Sandy Bridge microarchitecture.", 220 preset!(westmere && has_avx), 221 ); 222 settings.add_preset( 223 "corei7-avx", 224 "Core i7 AVX microarchitecture.", 225 preset!(sandy_bridge), 226 ); 227 let ivy_bridge = settings.add_preset( 228 "ivybridge", 229 "Ivy Bridge microarchitecture.", 230 preset!(sandy_bridge), 231 ); 232 settings.add_preset( 233 "core-avx-i", 234 "Intel Core CPU with 64-bit extensions.", 235 preset!(ivy_bridge), 236 ); 237 let haswell = settings.add_preset( 238 "haswell", 239 "Haswell microarchitecture.", 240 preset!(ivy_bridge && has_avx2 && has_bmi1 && has_bmi2 && has_fma && has_lzcnt), 241 ); 242 settings.add_preset( 243 "core-avx2", 244 "Intel Core CPU with AVX2 extensions.", 245 preset!(haswell), 246 ); 247 let broadwell = settings.add_preset( 248 "broadwell", 249 "Broadwell microarchitecture.", 250 preset!(haswell), 251 ); 252 let skylake = settings.add_preset("skylake", "Skylake microarchitecture.", preset!(broadwell)); 253 let knights_landing = settings.add_preset( 254 "knl", 255 "Knights Landing microarchitecture.", 256 preset!( 257 has_popcnt 258 && has_avx512f 259 && has_fma 260 && has_bmi1 261 && has_bmi2 262 && has_lzcnt 263 && has_cmpxchg16b 264 ), 265 ); 266 settings.add_preset( 267 "knm", 268 "Knights Mill microarchitecture.", 269 preset!(knights_landing), 270 ); 271 let skylake_avx512 = settings.add_preset( 272 "skylake-avx512", 273 "Skylake AVX512 microarchitecture.", 274 preset!(broadwell && has_avx512f && has_avx512dq && has_avx512vl), 275 ); 276 settings.add_preset( 277 "skx", 278 "Skylake AVX512 microarchitecture.", 279 preset!(skylake_avx512), 280 ); 281 let cascadelake = settings.add_preset( 282 "cascadelake", 283 "Cascade Lake microarchitecture.", 284 preset!(skylake_avx512), 285 ); 286 settings.add_preset( 287 "cooperlake", 288 "Cooper Lake microarchitecture.", 289 preset!(cascadelake), 290 ); 291 let cannonlake = settings.add_preset( 292 "cannonlake", 293 "Canon Lake microarchitecture.", 294 preset!(skylake && has_avx512f && has_avx512dq && has_avx512vl && has_avx512vbmi), 295 ); 296 let icelake_client = settings.add_preset( 297 "icelake-client", 298 "Ice Lake microarchitecture.", 299 preset!(cannonlake && has_avx512bitalg), 300 ); 301 // LLVM doesn't use the name "icelake" but Cranelift did in the past; alias it 302 settings.add_preset( 303 "icelake", 304 "Ice Lake microarchitecture", 305 preset!(icelake_client), 306 ); 307 let icelake_server = settings.add_preset( 308 "icelake-server", 309 "Ice Lake (server) microarchitecture.", 310 preset!(icelake_client), 311 ); 312 settings.add_preset( 313 "tigerlake", 314 "Tiger Lake microarchitecture.", 315 preset!(icelake_client), 316 ); 317 let sapphire_rapids = settings.add_preset( 318 "sapphirerapids", 319 "Sapphire Rapids microarchitecture.", 320 preset!(icelake_server), 321 ); 322 settings.add_preset( 323 "raptorlake", 324 "Raptor Lake microarchitecture.", 325 preset!(alderlake), 326 ); 327 settings.add_preset( 328 "meteorlake", 329 "Meteor Lake microarchitecture.", 330 preset!(alderlake), 331 ); 332 settings.add_preset( 333 "graniterapids", 334 "Granite Rapids microarchitecture.", 335 preset!(sapphire_rapids), 336 ); 337 338 // AMD CPUs 339 340 settings.add_preset("opteron", "Opteron microarchitecture.", preset!()); 341 settings.add_preset("k8", "K8 Hammer microarchitecture.", preset!()); 342 settings.add_preset("athlon64", "Athlon64 microarchitecture.", preset!()); 343 settings.add_preset("athlon-fx", "Athlon FX microarchitecture.", preset!()); 344 settings.add_preset( 345 "opteron-sse3", 346 "Opteron microarchitecture with support for SSE3 instructions.", 347 preset!(sse3 && has_cmpxchg16b), 348 ); 349 settings.add_preset( 350 "k8-sse3", 351 "K8 Hammer microarchitecture with support for SSE3 instructions.", 352 preset!(sse3 && has_cmpxchg16b), 353 ); 354 settings.add_preset( 355 "athlon64-sse3", 356 "Athlon 64 microarchitecture with support for SSE3 instructions.", 357 preset!(sse3 && has_cmpxchg16b), 358 ); 359 let barcelona = settings.add_preset( 360 "barcelona", 361 "Barcelona microarchitecture.", 362 preset!(has_popcnt && has_lzcnt && has_cmpxchg16b), 363 ); 364 settings.add_preset( 365 "amdfam10", 366 "AMD Family 10h microarchitecture", 367 preset!(barcelona), 368 ); 369 370 let btver1 = settings.add_preset( 371 "btver1", 372 "Bobcat microarchitecture.", 373 preset!(ssse3 && has_lzcnt && has_popcnt && has_cmpxchg16b), 374 ); 375 settings.add_preset( 376 "btver2", 377 "Jaguar microarchitecture.", 378 preset!(btver1 && has_avx && has_bmi1), 379 ); 380 381 let bdver1 = settings.add_preset( 382 "bdver1", 383 "Bulldozer microarchitecture", 384 preset!(has_lzcnt && has_popcnt && ssse3 && has_cmpxchg16b), 385 ); 386 let bdver2 = settings.add_preset( 387 "bdver2", 388 "Piledriver microarchitecture.", 389 preset!(bdver1 && has_bmi1), 390 ); 391 let bdver3 = settings.add_preset("bdver3", "Steamroller microarchitecture.", preset!(bdver2)); 392 settings.add_preset( 393 "bdver4", 394 "Excavator microarchitecture.", 395 preset!(bdver3 && has_avx2 && has_bmi2), 396 ); 397 398 let znver1 = settings.add_preset( 399 "znver1", 400 "Zen (first generation) microarchitecture.", 401 preset!( 402 sse42 && has_popcnt && has_bmi1 && has_bmi2 && has_lzcnt && has_fma && has_cmpxchg16b 403 ), 404 ); 405 let znver2 = settings.add_preset( 406 "znver2", 407 "Zen (second generation) microarchitecture.", 408 preset!(znver1), 409 ); 410 let znver3 = settings.add_preset( 411 "znver3", 412 "Zen (third generation) microarchitecture.", 413 preset!(znver2), 414 ); 415 settings.add_preset( 416 "znver4", 417 "Zen (fourth generation) microarchitecture.", 418 preset!( 419 znver3 420 && has_avx512bitalg 421 && has_avx512dq 422 && has_avx512f 423 && has_avx512vbmi 424 && has_avx512vl 425 ), 426 ); 427 428 // Generic 429 430 settings.add_preset("x86-64", "Generic x86-64 microarchitecture.", preset!()); 431 let x86_64_v2 = settings.add_preset( 432 "x86-64-v2", 433 "Generic x86-64 (V2) microarchitecture.", 434 preset!(sse42 && has_popcnt && has_cmpxchg16b), 435 ); 436 let x86_64_v3 = settings.add_preset( 437 "x84_64_v3", 438 "Generic x86_64 (V3) microarchitecture.", 439 preset!(x86_64_v2 && has_bmi1 && has_bmi2 && has_fma && has_lzcnt && has_avx2), 440 ); 441 settings.add_preset( 442 "x86_64_v4", 443 "Generic x86_64 (V4) microarchitecture.", 444 preset!(x86_64_v3 && has_avx512dq && has_avx512vl), 445 ); 446 447 TargetIsa::new("x86", settings.build()) 448 } 449