1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897 |
- //===--- X86.cpp - Implement X86 target feature support -------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file implements X86 TargetInfo objects.
- //
- //===----------------------------------------------------------------------===//
- #include "X86.h"
- #include "clang/Basic/Builtins.h"
- #include "clang/Basic/Diagnostic.h"
- #include "clang/Basic/TargetBuiltins.h"
- #include "llvm/ADT/StringExtras.h"
- #include "llvm/ADT/StringRef.h"
- #include "llvm/ADT/StringSwitch.h"
- #include "llvm/Support/TargetParser.h"
- namespace clang {
- namespace targets {
- const Builtin::Info BuiltinInfoX86[] = {
- #define BUILTIN(ID, TYPE, ATTRS) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
- #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
- #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
- {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
- #include "clang/Basic/BuiltinsX86.def"
- #define BUILTIN(ID, TYPE, ATTRS) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
- #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
- #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
- {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
- #include "clang/Basic/BuiltinsX86_64.def"
- };
- static const char *const GCCRegNames[] = {
- "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
- "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
- "argp", "flags", "fpcr", "fpsr", "dirflag", "frame", "xmm0", "xmm1",
- "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "mm0", "mm1",
- "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", "r8", "r9",
- "r10", "r11", "r12", "r13", "r14", "r15", "xmm8", "xmm9",
- "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15", "ymm0", "ymm1",
- "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", "ymm8", "ymm9",
- "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15", "xmm16", "xmm17",
- "xmm18", "xmm19", "xmm20", "xmm21", "xmm22", "xmm23", "xmm24", "xmm25",
- "xmm26", "xmm27", "xmm28", "xmm29", "xmm30", "xmm31", "ymm16", "ymm17",
- "ymm18", "ymm19", "ymm20", "ymm21", "ymm22", "ymm23", "ymm24", "ymm25",
- "ymm26", "ymm27", "ymm28", "ymm29", "ymm30", "ymm31", "zmm0", "zmm1",
- "zmm2", "zmm3", "zmm4", "zmm5", "zmm6", "zmm7", "zmm8", "zmm9",
- "zmm10", "zmm11", "zmm12", "zmm13", "zmm14", "zmm15", "zmm16", "zmm17",
- "zmm18", "zmm19", "zmm20", "zmm21", "zmm22", "zmm23", "zmm24", "zmm25",
- "zmm26", "zmm27", "zmm28", "zmm29", "zmm30", "zmm31", "k0", "k1",
- "k2", "k3", "k4", "k5", "k6", "k7",
- "cr0", "cr2", "cr3", "cr4", "cr8",
- "dr0", "dr1", "dr2", "dr3", "dr6", "dr7",
- "bnd0", "bnd1", "bnd2", "bnd3",
- };
- const TargetInfo::AddlRegName AddlRegNames[] = {
- {{"al", "ah", "eax", "rax"}, 0},
- {{"bl", "bh", "ebx", "rbx"}, 3},
- {{"cl", "ch", "ecx", "rcx"}, 2},
- {{"dl", "dh", "edx", "rdx"}, 1},
- {{"esi", "rsi"}, 4},
- {{"edi", "rdi"}, 5},
- {{"esp", "rsp"}, 7},
- {{"ebp", "rbp"}, 6},
- {{"r8d", "r8w", "r8b"}, 38},
- {{"r9d", "r9w", "r9b"}, 39},
- {{"r10d", "r10w", "r10b"}, 40},
- {{"r11d", "r11w", "r11b"}, 41},
- {{"r12d", "r12w", "r12b"}, 42},
- {{"r13d", "r13w", "r13b"}, 43},
- {{"r14d", "r14w", "r14b"}, 44},
- {{"r15d", "r15w", "r15b"}, 45},
- };
- } // namespace targets
- } // namespace clang
- using namespace clang;
- using namespace clang::targets;
- bool X86TargetInfo::setFPMath(StringRef Name) {
- if (Name == "387") {
- FPMath = FP_387;
- return true;
- }
- if (Name == "sse") {
- FPMath = FP_SSE;
- return true;
- }
- return false;
- }
- bool X86TargetInfo::initFeatureMap(
- llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
- const std::vector<std::string> &FeaturesVec) const {
- // FIXME: This *really* should not be here.
- // X86_64 always has SSE2.
- if (getTriple().getArch() == llvm::Triple::x86_64)
- setFeatureEnabledImpl(Features, "sse2", true);
- const CPUKind Kind = getCPUKind(CPU);
- // Enable X87 for all X86 processors but Lakemont.
- if (Kind != CK_Lakemont)
- setFeatureEnabledImpl(Features, "x87", true);
- // Enable cmpxchg8 for i586 and greater CPUs. Include generic for backwards
- // compatibility.
- if (Kind >= CK_i586 || Kind == CK_Generic)
- setFeatureEnabledImpl(Features, "cx8", true);
- switch (Kind) {
- case CK_Generic:
- case CK_i386:
- case CK_i486:
- case CK_i586:
- case CK_Pentium:
- case CK_PentiumPro:
- case CK_i686:
- case CK_Lakemont:
- break;
- case CK_PentiumMMX:
- case CK_Pentium2:
- case CK_K6:
- case CK_WinChipC6:
- setFeatureEnabledImpl(Features, "mmx", true);
- break;
- case CK_Cooperlake:
- // CPX inherits all CLX features plus AVX512BF16
- setFeatureEnabledImpl(Features, "avx512bf16", true);
- LLVM_FALLTHROUGH;
- case CK_Cascadelake:
- // CLX inherits all SKX features plus AVX512VNNI
- setFeatureEnabledImpl(Features, "avx512vnni", true);
- LLVM_FALLTHROUGH;
- case CK_SkylakeServer:
- setFeatureEnabledImpl(Features, "avx512f", true);
- setFeatureEnabledImpl(Features, "avx512cd", true);
- setFeatureEnabledImpl(Features, "avx512dq", true);
- setFeatureEnabledImpl(Features, "avx512bw", true);
- setFeatureEnabledImpl(Features, "avx512vl", true);
- setFeatureEnabledImpl(Features, "clwb", true);
- setFeatureEnabledImpl(Features, "pku", true);
- // SkylakeServer cores inherits all SKL features, except SGX
- goto SkylakeCommon;
- case CK_Tigerlake:
- setFeatureEnabledImpl(Features, "avx512vp2intersect", true);
- setFeatureEnabledImpl(Features, "movdiri", true);
- setFeatureEnabledImpl(Features, "movdir64b", true);
- setFeatureEnabledImpl(Features, "shstk", true);
- // Tigerlake cores inherits IcelakeClient, except pconfig and wbnoinvd
- goto IcelakeCommon;
- case CK_IcelakeServer:
- setFeatureEnabledImpl(Features, "pconfig", true);
- setFeatureEnabledImpl(Features, "wbnoinvd", true);
- LLVM_FALLTHROUGH;
- case CK_IcelakeClient:
- IcelakeCommon:
- setFeatureEnabledImpl(Features, "vaes", true);
- setFeatureEnabledImpl(Features, "gfni", true);
- setFeatureEnabledImpl(Features, "vpclmulqdq", true);
- setFeatureEnabledImpl(Features, "avx512bitalg", true);
- setFeatureEnabledImpl(Features, "avx512vbmi2", true);
- setFeatureEnabledImpl(Features, "avx512vnni", true);
- setFeatureEnabledImpl(Features, "avx512vpopcntdq", true);
- setFeatureEnabledImpl(Features, "rdpid", true);
- setFeatureEnabledImpl(Features, "clwb", true);
- LLVM_FALLTHROUGH;
- case CK_Cannonlake:
- setFeatureEnabledImpl(Features, "avx512f", true);
- setFeatureEnabledImpl(Features, "avx512cd", true);
- setFeatureEnabledImpl(Features, "avx512dq", true);
- setFeatureEnabledImpl(Features, "avx512bw", true);
- setFeatureEnabledImpl(Features, "avx512vl", true);
- setFeatureEnabledImpl(Features, "avx512ifma", true);
- setFeatureEnabledImpl(Features, "avx512vbmi", true);
- setFeatureEnabledImpl(Features, "pku", true);
- setFeatureEnabledImpl(Features, "sha", true);
- LLVM_FALLTHROUGH;
- case CK_SkylakeClient:
- setFeatureEnabledImpl(Features, "sgx", true);
- // SkylakeServer cores inherits all SKL features, except SGX
- SkylakeCommon:
- setFeatureEnabledImpl(Features, "xsavec", true);
- setFeatureEnabledImpl(Features, "xsaves", true);
- setFeatureEnabledImpl(Features, "clflushopt", true);
- setFeatureEnabledImpl(Features, "aes", true);
- LLVM_FALLTHROUGH;
- case CK_Broadwell:
- setFeatureEnabledImpl(Features, "rdseed", true);
- setFeatureEnabledImpl(Features, "adx", true);
- setFeatureEnabledImpl(Features, "prfchw", true);
- LLVM_FALLTHROUGH;
- case CK_Haswell:
- setFeatureEnabledImpl(Features, "avx2", true);
- setFeatureEnabledImpl(Features, "lzcnt", true);
- setFeatureEnabledImpl(Features, "bmi", true);
- setFeatureEnabledImpl(Features, "bmi2", true);
- setFeatureEnabledImpl(Features, "fma", true);
- setFeatureEnabledImpl(Features, "invpcid", true);
- setFeatureEnabledImpl(Features, "movbe", true);
- LLVM_FALLTHROUGH;
- case CK_IvyBridge:
- setFeatureEnabledImpl(Features, "rdrnd", true);
- setFeatureEnabledImpl(Features, "f16c", true);
- setFeatureEnabledImpl(Features, "fsgsbase", true);
- LLVM_FALLTHROUGH;
- case CK_SandyBridge:
- setFeatureEnabledImpl(Features, "avx", true);
- setFeatureEnabledImpl(Features, "xsave", true);
- setFeatureEnabledImpl(Features, "xsaveopt", true);
- LLVM_FALLTHROUGH;
- case CK_Westmere:
- setFeatureEnabledImpl(Features, "pclmul", true);
- LLVM_FALLTHROUGH;
- case CK_Nehalem:
- setFeatureEnabledImpl(Features, "sse4.2", true);
- LLVM_FALLTHROUGH;
- case CK_Penryn:
- setFeatureEnabledImpl(Features, "sse4.1", true);
- LLVM_FALLTHROUGH;
- case CK_Core2:
- setFeatureEnabledImpl(Features, "ssse3", true);
- setFeatureEnabledImpl(Features, "sahf", true);
- LLVM_FALLTHROUGH;
- case CK_Nocona:
- setFeatureEnabledImpl(Features, "cx16", true);
- LLVM_FALLTHROUGH;
- case CK_Yonah:
- case CK_Prescott:
- setFeatureEnabledImpl(Features, "sse3", true);
- LLVM_FALLTHROUGH;
- case CK_PentiumM:
- case CK_Pentium4:
- case CK_x86_64:
- setFeatureEnabledImpl(Features, "sse2", true);
- LLVM_FALLTHROUGH;
- case CK_Pentium3:
- case CK_C3_2:
- setFeatureEnabledImpl(Features, "sse", true);
- setFeatureEnabledImpl(Features, "fxsr", true);
- break;
- case CK_Tremont:
- setFeatureEnabledImpl(Features, "cldemote", true);
- setFeatureEnabledImpl(Features, "movdiri", true);
- setFeatureEnabledImpl(Features, "movdir64b", true);
- setFeatureEnabledImpl(Features, "gfni", true);
- setFeatureEnabledImpl(Features, "waitpkg", true);
- LLVM_FALLTHROUGH;
- case CK_GoldmontPlus:
- setFeatureEnabledImpl(Features, "ptwrite", true);
- setFeatureEnabledImpl(Features, "rdpid", true);
- setFeatureEnabledImpl(Features, "sgx", true);
- LLVM_FALLTHROUGH;
- case CK_Goldmont:
- setFeatureEnabledImpl(Features, "sha", true);
- setFeatureEnabledImpl(Features, "rdseed", true);
- setFeatureEnabledImpl(Features, "xsave", true);
- setFeatureEnabledImpl(Features, "xsaveopt", true);
- setFeatureEnabledImpl(Features, "xsavec", true);
- setFeatureEnabledImpl(Features, "xsaves", true);
- setFeatureEnabledImpl(Features, "clflushopt", true);
- setFeatureEnabledImpl(Features, "fsgsbase", true);
- setFeatureEnabledImpl(Features, "aes", true);
- LLVM_FALLTHROUGH;
- case CK_Silvermont:
- setFeatureEnabledImpl(Features, "rdrnd", true);
- setFeatureEnabledImpl(Features, "pclmul", true);
- setFeatureEnabledImpl(Features, "sse4.2", true);
- setFeatureEnabledImpl(Features, "prfchw", true);
- LLVM_FALLTHROUGH;
- case CK_Bonnell:
- setFeatureEnabledImpl(Features, "movbe", true);
- setFeatureEnabledImpl(Features, "ssse3", true);
- setFeatureEnabledImpl(Features, "fxsr", true);
- setFeatureEnabledImpl(Features, "cx16", true);
- setFeatureEnabledImpl(Features, "sahf", true);
- break;
- case CK_KNM:
- // TODO: Add avx5124fmaps/avx5124vnniw.
- setFeatureEnabledImpl(Features, "avx512vpopcntdq", true);
- LLVM_FALLTHROUGH;
- case CK_KNL:
- setFeatureEnabledImpl(Features, "avx512f", true);
- setFeatureEnabledImpl(Features, "avx512cd", true);
- setFeatureEnabledImpl(Features, "avx512er", true);
- setFeatureEnabledImpl(Features, "avx512pf", true);
- setFeatureEnabledImpl(Features, "prfchw", true);
- setFeatureEnabledImpl(Features, "prefetchwt1", true);
- setFeatureEnabledImpl(Features, "fxsr", true);
- setFeatureEnabledImpl(Features, "rdseed", true);
- setFeatureEnabledImpl(Features, "adx", true);
- setFeatureEnabledImpl(Features, "lzcnt", true);
- setFeatureEnabledImpl(Features, "bmi", true);
- setFeatureEnabledImpl(Features, "bmi2", true);
- setFeatureEnabledImpl(Features, "fma", true);
- setFeatureEnabledImpl(Features, "rdrnd", true);
- setFeatureEnabledImpl(Features, "f16c", true);
- setFeatureEnabledImpl(Features, "fsgsbase", true);
- setFeatureEnabledImpl(Features, "aes", true);
- setFeatureEnabledImpl(Features, "pclmul", true);
- setFeatureEnabledImpl(Features, "cx16", true);
- setFeatureEnabledImpl(Features, "xsaveopt", true);
- setFeatureEnabledImpl(Features, "xsave", true);
- setFeatureEnabledImpl(Features, "movbe", true);
- setFeatureEnabledImpl(Features, "sahf", true);
- break;
- case CK_K6_2:
- case CK_K6_3:
- case CK_WinChip2:
- case CK_C3:
- setFeatureEnabledImpl(Features, "3dnow", true);
- break;
- case CK_AMDFAM10:
- setFeatureEnabledImpl(Features, "sse4a", true);
- setFeatureEnabledImpl(Features, "lzcnt", true);
- setFeatureEnabledImpl(Features, "popcnt", true);
- setFeatureEnabledImpl(Features, "sahf", true);
- LLVM_FALLTHROUGH;
- case CK_K8SSE3:
- setFeatureEnabledImpl(Features, "sse3", true);
- LLVM_FALLTHROUGH;
- case CK_K8:
- setFeatureEnabledImpl(Features, "sse2", true);
- LLVM_FALLTHROUGH;
- case CK_AthlonXP:
- setFeatureEnabledImpl(Features, "sse", true);
- setFeatureEnabledImpl(Features, "fxsr", true);
- LLVM_FALLTHROUGH;
- case CK_Athlon:
- case CK_Geode:
- setFeatureEnabledImpl(Features, "3dnowa", true);
- break;
- case CK_BTVER2:
- setFeatureEnabledImpl(Features, "avx", true);
- setFeatureEnabledImpl(Features, "aes", true);
- setFeatureEnabledImpl(Features, "pclmul", true);
- setFeatureEnabledImpl(Features, "bmi", true);
- setFeatureEnabledImpl(Features, "f16c", true);
- setFeatureEnabledImpl(Features, "xsaveopt", true);
- setFeatureEnabledImpl(Features, "movbe", true);
- LLVM_FALLTHROUGH;
- case CK_BTVER1:
- setFeatureEnabledImpl(Features, "ssse3", true);
- setFeatureEnabledImpl(Features, "sse4a", true);
- setFeatureEnabledImpl(Features, "lzcnt", true);
- setFeatureEnabledImpl(Features, "popcnt", true);
- setFeatureEnabledImpl(Features, "prfchw", true);
- setFeatureEnabledImpl(Features, "cx16", true);
- setFeatureEnabledImpl(Features, "fxsr", true);
- setFeatureEnabledImpl(Features, "sahf", true);
- break;
- case CK_ZNVER2:
- setFeatureEnabledImpl(Features, "clwb", true);
- setFeatureEnabledImpl(Features, "rdpid", true);
- setFeatureEnabledImpl(Features, "wbnoinvd", true);
- LLVM_FALLTHROUGH;
- case CK_ZNVER1:
- setFeatureEnabledImpl(Features, "adx", true);
- setFeatureEnabledImpl(Features, "aes", true);
- setFeatureEnabledImpl(Features, "avx2", true);
- setFeatureEnabledImpl(Features, "bmi", true);
- setFeatureEnabledImpl(Features, "bmi2", true);
- setFeatureEnabledImpl(Features, "clflushopt", true);
- setFeatureEnabledImpl(Features, "clzero", true);
- setFeatureEnabledImpl(Features, "cx16", true);
- setFeatureEnabledImpl(Features, "f16c", true);
- setFeatureEnabledImpl(Features, "fma", true);
- setFeatureEnabledImpl(Features, "fsgsbase", true);
- setFeatureEnabledImpl(Features, "fxsr", true);
- setFeatureEnabledImpl(Features, "lzcnt", true);
- setFeatureEnabledImpl(Features, "mwaitx", true);
- setFeatureEnabledImpl(Features, "movbe", true);
- setFeatureEnabledImpl(Features, "pclmul", true);
- setFeatureEnabledImpl(Features, "popcnt", true);
- setFeatureEnabledImpl(Features, "prfchw", true);
- setFeatureEnabledImpl(Features, "rdrnd", true);
- setFeatureEnabledImpl(Features, "rdseed", true);
- setFeatureEnabledImpl(Features, "sahf", true);
- setFeatureEnabledImpl(Features, "sha", true);
- setFeatureEnabledImpl(Features, "sse4a", true);
- setFeatureEnabledImpl(Features, "xsave", true);
- setFeatureEnabledImpl(Features, "xsavec", true);
- setFeatureEnabledImpl(Features, "xsaveopt", true);
- setFeatureEnabledImpl(Features, "xsaves", true);
- break;
- case CK_BDVER4:
- setFeatureEnabledImpl(Features, "avx2", true);
- setFeatureEnabledImpl(Features, "bmi2", true);
- setFeatureEnabledImpl(Features, "mwaitx", true);
- LLVM_FALLTHROUGH;
- case CK_BDVER3:
- setFeatureEnabledImpl(Features, "fsgsbase", true);
- setFeatureEnabledImpl(Features, "xsaveopt", true);
- LLVM_FALLTHROUGH;
- case CK_BDVER2:
- setFeatureEnabledImpl(Features, "bmi", true);
- setFeatureEnabledImpl(Features, "fma", true);
- setFeatureEnabledImpl(Features, "f16c", true);
- setFeatureEnabledImpl(Features, "tbm", true);
- LLVM_FALLTHROUGH;
- case CK_BDVER1:
- // xop implies avx, sse4a and fma4.
- setFeatureEnabledImpl(Features, "xop", true);
- setFeatureEnabledImpl(Features, "lwp", true);
- setFeatureEnabledImpl(Features, "lzcnt", true);
- setFeatureEnabledImpl(Features, "aes", true);
- setFeatureEnabledImpl(Features, "pclmul", true);
- setFeatureEnabledImpl(Features, "prfchw", true);
- setFeatureEnabledImpl(Features, "cx16", true);
- setFeatureEnabledImpl(Features, "fxsr", true);
- setFeatureEnabledImpl(Features, "xsave", true);
- setFeatureEnabledImpl(Features, "sahf", true);
- break;
- }
- if (!TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec))
- return false;
- // Can't do this earlier because we need to be able to explicitly enable
- // or disable these features and the things that they depend upon.
- // Enable popcnt if sse4.2 is enabled and popcnt is not explicitly disabled.
- auto I = Features.find("sse4.2");
- if (I != Features.end() && I->getValue() &&
- llvm::find(FeaturesVec, "-popcnt") == FeaturesVec.end())
- Features["popcnt"] = true;
- // Enable prfchw if 3DNow! is enabled and prfchw is not explicitly disabled.
- I = Features.find("3dnow");
- if (I != Features.end() && I->getValue() &&
- llvm::find(FeaturesVec, "-prfchw") == FeaturesVec.end())
- Features["prfchw"] = true;
- // Additionally, if SSE is enabled and mmx is not explicitly disabled,
- // then enable MMX.
- I = Features.find("sse");
- if (I != Features.end() && I->getValue() &&
- llvm::find(FeaturesVec, "-mmx") == FeaturesVec.end())
- Features["mmx"] = true;
- return true;
- }
- void X86TargetInfo::setSSELevel(llvm::StringMap<bool> &Features,
- X86SSEEnum Level, bool Enabled) {
- if (Enabled) {
- switch (Level) {
- case AVX512F:
- Features["avx512f"] = true;
- Features["fma"] = true;
- Features["f16c"] = true;
- LLVM_FALLTHROUGH;
- case AVX2:
- Features["avx2"] = true;
- LLVM_FALLTHROUGH;
- case AVX:
- Features["avx"] = true;
- Features["xsave"] = true;
- LLVM_FALLTHROUGH;
- case SSE42:
- Features["sse4.2"] = true;
- LLVM_FALLTHROUGH;
- case SSE41:
- Features["sse4.1"] = true;
- LLVM_FALLTHROUGH;
- case SSSE3:
- Features["ssse3"] = true;
- LLVM_FALLTHROUGH;
- case SSE3:
- Features["sse3"] = true;
- LLVM_FALLTHROUGH;
- case SSE2:
- Features["sse2"] = true;
- LLVM_FALLTHROUGH;
- case SSE1:
- Features["sse"] = true;
- LLVM_FALLTHROUGH;
- case NoSSE:
- break;
- }
- return;
- }
- switch (Level) {
- case NoSSE:
- case SSE1:
- Features["sse"] = false;
- LLVM_FALLTHROUGH;
- case SSE2:
- Features["sse2"] = Features["pclmul"] = Features["aes"] = false;
- Features["sha"] = Features["gfni"] = false;
- LLVM_FALLTHROUGH;
- case SSE3:
- Features["sse3"] = false;
- setXOPLevel(Features, NoXOP, false);
- LLVM_FALLTHROUGH;
- case SSSE3:
- Features["ssse3"] = false;
- LLVM_FALLTHROUGH;
- case SSE41:
- Features["sse4.1"] = false;
- LLVM_FALLTHROUGH;
- case SSE42:
- Features["sse4.2"] = false;
- LLVM_FALLTHROUGH;
- case AVX:
- Features["fma"] = Features["avx"] = Features["f16c"] = false;
- Features["xsave"] = Features["xsaveopt"] = Features["vaes"] = false;
- Features["vpclmulqdq"] = false;
- setXOPLevel(Features, FMA4, false);
- LLVM_FALLTHROUGH;
- case AVX2:
- Features["avx2"] = false;
- LLVM_FALLTHROUGH;
- case AVX512F:
- Features["avx512f"] = Features["avx512cd"] = Features["avx512er"] = false;
- Features["avx512pf"] = Features["avx512dq"] = Features["avx512bw"] = false;
- Features["avx512vl"] = Features["avx512vbmi"] = false;
- Features["avx512ifma"] = Features["avx512vpopcntdq"] = false;
- Features["avx512bitalg"] = Features["avx512vnni"] = false;
- Features["avx512vbmi2"] = Features["avx512bf16"] = false;
- Features["avx512vp2intersect"] = false;
- break;
- }
- }
- void X86TargetInfo::setMMXLevel(llvm::StringMap<bool> &Features,
- MMX3DNowEnum Level, bool Enabled) {
- if (Enabled) {
- switch (Level) {
- case AMD3DNowAthlon:
- Features["3dnowa"] = true;
- LLVM_FALLTHROUGH;
- case AMD3DNow:
- Features["3dnow"] = true;
- LLVM_FALLTHROUGH;
- case MMX:
- Features["mmx"] = true;
- LLVM_FALLTHROUGH;
- case NoMMX3DNow:
- break;
- }
- return;
- }
- switch (Level) {
- case NoMMX3DNow:
- case MMX:
- Features["mmx"] = false;
- LLVM_FALLTHROUGH;
- case AMD3DNow:
- Features["3dnow"] = false;
- LLVM_FALLTHROUGH;
- case AMD3DNowAthlon:
- Features["3dnowa"] = false;
- break;
- }
- }
- void X86TargetInfo::setXOPLevel(llvm::StringMap<bool> &Features, XOPEnum Level,
- bool Enabled) {
- if (Enabled) {
- switch (Level) {
- case XOP:
- Features["xop"] = true;
- LLVM_FALLTHROUGH;
- case FMA4:
- Features["fma4"] = true;
- setSSELevel(Features, AVX, true);
- LLVM_FALLTHROUGH;
- case SSE4A:
- Features["sse4a"] = true;
- setSSELevel(Features, SSE3, true);
- LLVM_FALLTHROUGH;
- case NoXOP:
- break;
- }
- return;
- }
- switch (Level) {
- case NoXOP:
- case SSE4A:
- Features["sse4a"] = false;
- LLVM_FALLTHROUGH;
- case FMA4:
- Features["fma4"] = false;
- LLVM_FALLTHROUGH;
- case XOP:
- Features["xop"] = false;
- break;
- }
- }
- void X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap<bool> &Features,
- StringRef Name, bool Enabled) {
- // This is a bit of a hack to deal with the sse4 target feature when used
- // as part of the target attribute. We handle sse4 correctly everywhere
- // else. See below for more information on how we handle the sse4 options.
- if (Name != "sse4")
- Features[Name] = Enabled;
- if (Name == "mmx") {
- setMMXLevel(Features, MMX, Enabled);
- } else if (Name == "sse") {
- setSSELevel(Features, SSE1, Enabled);
- } else if (Name == "sse2") {
- setSSELevel(Features, SSE2, Enabled);
- } else if (Name == "sse3") {
- setSSELevel(Features, SSE3, Enabled);
- } else if (Name == "ssse3") {
- setSSELevel(Features, SSSE3, Enabled);
- } else if (Name == "sse4.2") {
- setSSELevel(Features, SSE42, Enabled);
- } else if (Name == "sse4.1") {
- setSSELevel(Features, SSE41, Enabled);
- } else if (Name == "3dnow") {
- setMMXLevel(Features, AMD3DNow, Enabled);
- } else if (Name == "3dnowa") {
- setMMXLevel(Features, AMD3DNowAthlon, Enabled);
- } else if (Name == "aes") {
- if (Enabled)
- setSSELevel(Features, SSE2, Enabled);
- else
- Features["vaes"] = false;
- } else if (Name == "vaes") {
- if (Enabled) {
- setSSELevel(Features, AVX, Enabled);
- Features["aes"] = true;
- }
- } else if (Name == "pclmul") {
- if (Enabled)
- setSSELevel(Features, SSE2, Enabled);
- else
- Features["vpclmulqdq"] = false;
- } else if (Name == "vpclmulqdq") {
- if (Enabled) {
- setSSELevel(Features, AVX, Enabled);
- Features["pclmul"] = true;
- }
- } else if (Name == "gfni") {
- if (Enabled)
- setSSELevel(Features, SSE2, Enabled);
- } else if (Name == "avx") {
- setSSELevel(Features, AVX, Enabled);
- } else if (Name == "avx2") {
- setSSELevel(Features, AVX2, Enabled);
- } else if (Name == "avx512f") {
- setSSELevel(Features, AVX512F, Enabled);
- } else if (Name.startswith("avx512")) {
- if (Enabled)
- setSSELevel(Features, AVX512F, Enabled);
- // Enable BWI instruction if certain features are being enabled.
- if ((Name == "avx512vbmi" || Name == "avx512vbmi2" ||
- Name == "avx512bitalg" || Name == "avx512bf16") && Enabled)
- Features["avx512bw"] = true;
- // Also disable some features if BWI is being disabled.
- if (Name == "avx512bw" && !Enabled) {
- Features["avx512vbmi"] = false;
- Features["avx512vbmi2"] = false;
- Features["avx512bitalg"] = false;
- Features["avx512bf16"] = false;
- }
- } else if (Name == "fma") {
- if (Enabled)
- setSSELevel(Features, AVX, Enabled);
- else
- setSSELevel(Features, AVX512F, Enabled);
- } else if (Name == "fma4") {
- setXOPLevel(Features, FMA4, Enabled);
- } else if (Name == "xop") {
- setXOPLevel(Features, XOP, Enabled);
- } else if (Name == "sse4a") {
- setXOPLevel(Features, SSE4A, Enabled);
- } else if (Name == "f16c") {
- if (Enabled)
- setSSELevel(Features, AVX, Enabled);
- else
- setSSELevel(Features, AVX512F, Enabled);
- } else if (Name == "sha") {
- if (Enabled)
- setSSELevel(Features, SSE2, Enabled);
- } else if (Name == "sse4") {
- // We can get here via the __target__ attribute since that's not controlled
- // via the -msse4/-mno-sse4 command line alias. Handle this the same way
- // here - turn on the sse4.2 if enabled, turn off the sse4.1 level if
- // disabled.
- if (Enabled)
- setSSELevel(Features, SSE42, Enabled);
- else
- setSSELevel(Features, SSE41, Enabled);
- } else if (Name == "xsave") {
- if (!Enabled)
- Features["xsaveopt"] = false;
- } else if (Name == "xsaveopt" || Name == "xsavec" || Name == "xsaves") {
- if (Enabled)
- Features["xsave"] = true;
- }
- }
- /// handleTargetFeatures - Perform initialization based on the user
- /// configured set of features.
- bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
- DiagnosticsEngine &Diags) {
- for (const auto &Feature : Features) {
- if (Feature[0] != '+')
- continue;
- if (Feature == "+aes") {
- HasAES = true;
- } else if (Feature == "+vaes") {
- HasVAES = true;
- } else if (Feature == "+pclmul") {
- HasPCLMUL = true;
- } else if (Feature == "+vpclmulqdq") {
- HasVPCLMULQDQ = true;
- } else if (Feature == "+lzcnt") {
- HasLZCNT = true;
- } else if (Feature == "+rdrnd") {
- HasRDRND = true;
- } else if (Feature == "+fsgsbase") {
- HasFSGSBASE = true;
- } else if (Feature == "+bmi") {
- HasBMI = true;
- } else if (Feature == "+bmi2") {
- HasBMI2 = true;
- } else if (Feature == "+popcnt") {
- HasPOPCNT = true;
- } else if (Feature == "+rtm") {
- HasRTM = true;
- } else if (Feature == "+prfchw") {
- HasPRFCHW = true;
- } else if (Feature == "+rdseed") {
- HasRDSEED = true;
- } else if (Feature == "+adx") {
- HasADX = true;
- } else if (Feature == "+tbm") {
- HasTBM = true;
- } else if (Feature == "+lwp") {
- HasLWP = true;
- } else if (Feature == "+fma") {
- HasFMA = true;
- } else if (Feature == "+f16c") {
- HasF16C = true;
- } else if (Feature == "+gfni") {
- HasGFNI = true;
- } else if (Feature == "+avx512cd") {
- HasAVX512CD = true;
- } else if (Feature == "+avx512vpopcntdq") {
- HasAVX512VPOPCNTDQ = true;
- } else if (Feature == "+avx512vnni") {
- HasAVX512VNNI = true;
- } else if (Feature == "+avx512bf16") {
- HasAVX512BF16 = true;
- } else if (Feature == "+avx512er") {
- HasAVX512ER = true;
- } else if (Feature == "+avx512pf") {
- HasAVX512PF = true;
- } else if (Feature == "+avx512dq") {
- HasAVX512DQ = true;
- } else if (Feature == "+avx512bitalg") {
- HasAVX512BITALG = true;
- } else if (Feature == "+avx512bw") {
- HasAVX512BW = true;
- } else if (Feature == "+avx512vl") {
- HasAVX512VL = true;
- } else if (Feature == "+avx512vbmi") {
- HasAVX512VBMI = true;
- } else if (Feature == "+avx512vbmi2") {
- HasAVX512VBMI2 = true;
- } else if (Feature == "+avx512ifma") {
- HasAVX512IFMA = true;
- } else if (Feature == "+avx512vp2intersect") {
- HasAVX512VP2INTERSECT = true;
- } else if (Feature == "+sha") {
- HasSHA = true;
- } else if (Feature == "+shstk") {
- HasSHSTK = true;
- } else if (Feature == "+movbe") {
- HasMOVBE = true;
- } else if (Feature == "+sgx") {
- HasSGX = true;
- } else if (Feature == "+cx8") {
- HasCX8 = true;
- } else if (Feature == "+cx16") {
- HasCX16 = true;
- } else if (Feature == "+fxsr") {
- HasFXSR = true;
- } else if (Feature == "+xsave") {
- HasXSAVE = true;
- } else if (Feature == "+xsaveopt") {
- HasXSAVEOPT = true;
- } else if (Feature == "+xsavec") {
- HasXSAVEC = true;
- } else if (Feature == "+xsaves") {
- HasXSAVES = true;
- } else if (Feature == "+mwaitx") {
- HasMWAITX = true;
- } else if (Feature == "+pku") {
- HasPKU = true;
- } else if (Feature == "+clflushopt") {
- HasCLFLUSHOPT = true;
- } else if (Feature == "+clwb") {
- HasCLWB = true;
- } else if (Feature == "+wbnoinvd") {
- HasWBNOINVD = true;
- } else if (Feature == "+prefetchwt1") {
- HasPREFETCHWT1 = true;
- } else if (Feature == "+clzero") {
- HasCLZERO = true;
- } else if (Feature == "+cldemote") {
- HasCLDEMOTE = true;
- } else if (Feature == "+rdpid") {
- HasRDPID = true;
- } else if (Feature == "+retpoline-external-thunk") {
- HasRetpolineExternalThunk = true;
- } else if (Feature == "+sahf") {
- HasLAHFSAHF = true;
- } else if (Feature == "+waitpkg") {
- HasWAITPKG = true;
- } else if (Feature == "+movdiri") {
- HasMOVDIRI = true;
- } else if (Feature == "+movdir64b") {
- HasMOVDIR64B = true;
- } else if (Feature == "+pconfig") {
- HasPCONFIG = true;
- } else if (Feature == "+ptwrite") {
- HasPTWRITE = true;
- } else if (Feature == "+invpcid") {
- HasINVPCID = true;
- } else if (Feature == "+enqcmd") {
- HasENQCMD = true;
- }
- X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
- .Case("+avx512f", AVX512F)
- .Case("+avx2", AVX2)
- .Case("+avx", AVX)
- .Case("+sse4.2", SSE42)
- .Case("+sse4.1", SSE41)
- .Case("+ssse3", SSSE3)
- .Case("+sse3", SSE3)
- .Case("+sse2", SSE2)
- .Case("+sse", SSE1)
- .Default(NoSSE);
- SSELevel = std::max(SSELevel, Level);
- MMX3DNowEnum ThreeDNowLevel = llvm::StringSwitch<MMX3DNowEnum>(Feature)
- .Case("+3dnowa", AMD3DNowAthlon)
- .Case("+3dnow", AMD3DNow)
- .Case("+mmx", MMX)
- .Default(NoMMX3DNow);
- MMX3DNowLevel = std::max(MMX3DNowLevel, ThreeDNowLevel);
- XOPEnum XLevel = llvm::StringSwitch<XOPEnum>(Feature)
- .Case("+xop", XOP)
- .Case("+fma4", FMA4)
- .Case("+sse4a", SSE4A)
- .Default(NoXOP);
- XOPLevel = std::max(XOPLevel, XLevel);
- }
- // LLVM doesn't have a separate switch for fpmath, so only accept it if it
- // matches the selected sse level.
- if ((FPMath == FP_SSE && SSELevel < SSE1) ||
- (FPMath == FP_387 && SSELevel >= SSE1)) {
- Diags.Report(diag::err_target_unsupported_fpmath)
- << (FPMath == FP_SSE ? "sse" : "387");
- return false;
- }
- SimdDefaultAlign =
- hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
- return true;
- }
- /// X86TargetInfo::getTargetDefines - Return the set of the X86-specific macro
- /// definitions for this particular subtarget.
- void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
- MacroBuilder &Builder) const {
- // Inline assembly supports X86 flag outputs.
- Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__");
- std::string CodeModel = getTargetOpts().CodeModel;
- if (CodeModel == "default")
- CodeModel = "small";
- Builder.defineMacro("__code_model_" + CodeModel + "_");
- // Target identification.
- if (getTriple().getArch() == llvm::Triple::x86_64) {
- Builder.defineMacro("__amd64__");
- Builder.defineMacro("__amd64");
- Builder.defineMacro("__x86_64");
- Builder.defineMacro("__x86_64__");
- if (getTriple().getArchName() == "x86_64h") {
- Builder.defineMacro("__x86_64h");
- Builder.defineMacro("__x86_64h__");
- }
- } else {
- DefineStd(Builder, "i386", Opts);
- }
- Builder.defineMacro("__SEG_GS");
- Builder.defineMacro("__SEG_FS");
- Builder.defineMacro("__seg_gs", "__attribute__((address_space(256)))");
- Builder.defineMacro("__seg_fs", "__attribute__((address_space(257)))");
- // Subtarget options.
- // FIXME: We are hard-coding the tune parameters based on the CPU, but they
- // truly should be based on -mtune options.
- switch (CPU) {
- case CK_Generic:
- break;
- case CK_i386:
- // The rest are coming from the i386 define above.
- Builder.defineMacro("__tune_i386__");
- break;
- case CK_i486:
- case CK_WinChipC6:
- case CK_WinChip2:
- case CK_C3:
- defineCPUMacros(Builder, "i486");
- break;
- case CK_PentiumMMX:
- Builder.defineMacro("__pentium_mmx__");
- Builder.defineMacro("__tune_pentium_mmx__");
- LLVM_FALLTHROUGH;
- case CK_i586:
- case CK_Pentium:
- defineCPUMacros(Builder, "i586");
- defineCPUMacros(Builder, "pentium");
- break;
- case CK_Pentium3:
- case CK_PentiumM:
- Builder.defineMacro("__tune_pentium3__");
- LLVM_FALLTHROUGH;
- case CK_Pentium2:
- case CK_C3_2:
- Builder.defineMacro("__tune_pentium2__");
- LLVM_FALLTHROUGH;
- case CK_PentiumPro:
- case CK_i686:
- defineCPUMacros(Builder, "i686");
- defineCPUMacros(Builder, "pentiumpro");
- break;
- case CK_Pentium4:
- defineCPUMacros(Builder, "pentium4");
- break;
- case CK_Yonah:
- case CK_Prescott:
- case CK_Nocona:
- defineCPUMacros(Builder, "nocona");
- break;
- case CK_Core2:
- case CK_Penryn:
- defineCPUMacros(Builder, "core2");
- break;
- case CK_Bonnell:
- defineCPUMacros(Builder, "atom");
- break;
- case CK_Silvermont:
- defineCPUMacros(Builder, "slm");
- break;
- case CK_Goldmont:
- defineCPUMacros(Builder, "goldmont");
- break;
- case CK_GoldmontPlus:
- defineCPUMacros(Builder, "goldmont_plus");
- break;
- case CK_Tremont:
- defineCPUMacros(Builder, "tremont");
- break;
- case CK_Nehalem:
- case CK_Westmere:
- case CK_SandyBridge:
- case CK_IvyBridge:
- case CK_Haswell:
- case CK_Broadwell:
- case CK_SkylakeClient:
- case CK_SkylakeServer:
- case CK_Cascadelake:
- case CK_Cooperlake:
- case CK_Cannonlake:
- case CK_IcelakeClient:
- case CK_IcelakeServer:
- case CK_Tigerlake:
- // FIXME: Historically, we defined this legacy name, it would be nice to
- // remove it at some point. We've never exposed fine-grained names for
- // recent primary x86 CPUs, and we should keep it that way.
- defineCPUMacros(Builder, "corei7");
- break;
- case CK_KNL:
- defineCPUMacros(Builder, "knl");
- break;
- case CK_KNM:
- break;
- case CK_Lakemont:
- defineCPUMacros(Builder, "i586", /*Tuning*/false);
- defineCPUMacros(Builder, "pentium", /*Tuning*/false);
- Builder.defineMacro("__tune_lakemont__");
- break;
- case CK_K6_2:
- Builder.defineMacro("__k6_2__");
- Builder.defineMacro("__tune_k6_2__");
- LLVM_FALLTHROUGH;
- case CK_K6_3:
- if (CPU != CK_K6_2) { // In case of fallthrough
- // FIXME: GCC may be enabling these in cases where some other k6
- // architecture is specified but -m3dnow is explicitly provided. The
- // exact semantics need to be determined and emulated here.
- Builder.defineMacro("__k6_3__");
- Builder.defineMacro("__tune_k6_3__");
- }
- LLVM_FALLTHROUGH;
- case CK_K6:
- defineCPUMacros(Builder, "k6");
- break;
- case CK_Athlon:
- case CK_AthlonXP:
- defineCPUMacros(Builder, "athlon");
- if (SSELevel != NoSSE) {
- Builder.defineMacro("__athlon_sse__");
- Builder.defineMacro("__tune_athlon_sse__");
- }
- break;
- case CK_K8:
- case CK_K8SSE3:
- case CK_x86_64:
- defineCPUMacros(Builder, "k8");
- break;
- case CK_AMDFAM10:
- defineCPUMacros(Builder, "amdfam10");
- break;
- case CK_BTVER1:
- defineCPUMacros(Builder, "btver1");
- break;
- case CK_BTVER2:
- defineCPUMacros(Builder, "btver2");
- break;
- case CK_BDVER1:
- defineCPUMacros(Builder, "bdver1");
- break;
- case CK_BDVER2:
- defineCPUMacros(Builder, "bdver2");
- break;
- case CK_BDVER3:
- defineCPUMacros(Builder, "bdver3");
- break;
- case CK_BDVER4:
- defineCPUMacros(Builder, "bdver4");
- break;
- case CK_ZNVER1:
- defineCPUMacros(Builder, "znver1");
- break;
- case CK_ZNVER2:
- defineCPUMacros(Builder, "znver2");
- break;
- case CK_Geode:
- defineCPUMacros(Builder, "geode");
- break;
- }
- // Target properties.
- Builder.defineMacro("__REGISTER_PREFIX__", "");
- // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
- // functions in glibc header files that use FP Stack inline asm which the
- // backend can't deal with (PR879).
- Builder.defineMacro("__NO_MATH_INLINES");
- if (HasAES)
- Builder.defineMacro("__AES__");
- if (HasVAES)
- Builder.defineMacro("__VAES__");
- if (HasPCLMUL)
- Builder.defineMacro("__PCLMUL__");
- if (HasVPCLMULQDQ)
- Builder.defineMacro("__VPCLMULQDQ__");
- if (HasLZCNT)
- Builder.defineMacro("__LZCNT__");
- if (HasRDRND)
- Builder.defineMacro("__RDRND__");
- if (HasFSGSBASE)
- Builder.defineMacro("__FSGSBASE__");
- if (HasBMI)
- Builder.defineMacro("__BMI__");
- if (HasBMI2)
- Builder.defineMacro("__BMI2__");
- if (HasPOPCNT)
- Builder.defineMacro("__POPCNT__");
- if (HasRTM)
- Builder.defineMacro("__RTM__");
- if (HasPRFCHW)
- Builder.defineMacro("__PRFCHW__");
- if (HasRDSEED)
- Builder.defineMacro("__RDSEED__");
- if (HasADX)
- Builder.defineMacro("__ADX__");
- if (HasTBM)
- Builder.defineMacro("__TBM__");
- if (HasLWP)
- Builder.defineMacro("__LWP__");
- if (HasMWAITX)
- Builder.defineMacro("__MWAITX__");
- if (HasMOVBE)
- Builder.defineMacro("__MOVBE__");
- switch (XOPLevel) {
- case XOP:
- Builder.defineMacro("__XOP__");
- LLVM_FALLTHROUGH;
- case FMA4:
- Builder.defineMacro("__FMA4__");
- LLVM_FALLTHROUGH;
- case SSE4A:
- Builder.defineMacro("__SSE4A__");
- LLVM_FALLTHROUGH;
- case NoXOP:
- break;
- }
- if (HasFMA)
- Builder.defineMacro("__FMA__");
- if (HasF16C)
- Builder.defineMacro("__F16C__");
- if (HasGFNI)
- Builder.defineMacro("__GFNI__");
- if (HasAVX512CD)
- Builder.defineMacro("__AVX512CD__");
- if (HasAVX512VPOPCNTDQ)
- Builder.defineMacro("__AVX512VPOPCNTDQ__");
- if (HasAVX512VNNI)
- Builder.defineMacro("__AVX512VNNI__");
- if (HasAVX512BF16)
- Builder.defineMacro("__AVX512BF16__");
- if (HasAVX512ER)
- Builder.defineMacro("__AVX512ER__");
- if (HasAVX512PF)
- Builder.defineMacro("__AVX512PF__");
- if (HasAVX512DQ)
- Builder.defineMacro("__AVX512DQ__");
- if (HasAVX512BITALG)
- Builder.defineMacro("__AVX512BITALG__");
- if (HasAVX512BW)
- Builder.defineMacro("__AVX512BW__");
- if (HasAVX512VL)
- Builder.defineMacro("__AVX512VL__");
- if (HasAVX512VBMI)
- Builder.defineMacro("__AVX512VBMI__");
- if (HasAVX512VBMI2)
- Builder.defineMacro("__AVX512VBMI2__");
- if (HasAVX512IFMA)
- Builder.defineMacro("__AVX512IFMA__");
- if (HasAVX512VP2INTERSECT)
- Builder.defineMacro("__AVX512VP2INTERSECT__");
- if (HasSHA)
- Builder.defineMacro("__SHA__");
- if (HasFXSR)
- Builder.defineMacro("__FXSR__");
- if (HasXSAVE)
- Builder.defineMacro("__XSAVE__");
- if (HasXSAVEOPT)
- Builder.defineMacro("__XSAVEOPT__");
- if (HasXSAVEC)
- Builder.defineMacro("__XSAVEC__");
- if (HasXSAVES)
- Builder.defineMacro("__XSAVES__");
- if (HasPKU)
- Builder.defineMacro("__PKU__");
- if (HasCLFLUSHOPT)
- Builder.defineMacro("__CLFLUSHOPT__");
- if (HasCLWB)
- Builder.defineMacro("__CLWB__");
- if (HasWBNOINVD)
- Builder.defineMacro("__WBNOINVD__");
- if (HasSHSTK)
- Builder.defineMacro("__SHSTK__");
- if (HasSGX)
- Builder.defineMacro("__SGX__");
- if (HasPREFETCHWT1)
- Builder.defineMacro("__PREFETCHWT1__");
- if (HasCLZERO)
- Builder.defineMacro("__CLZERO__");
- if (HasRDPID)
- Builder.defineMacro("__RDPID__");
- if (HasCLDEMOTE)
- Builder.defineMacro("__CLDEMOTE__");
- if (HasWAITPKG)
- Builder.defineMacro("__WAITPKG__");
- if (HasMOVDIRI)
- Builder.defineMacro("__MOVDIRI__");
- if (HasMOVDIR64B)
- Builder.defineMacro("__MOVDIR64B__");
- if (HasPCONFIG)
- Builder.defineMacro("__PCONFIG__");
- if (HasPTWRITE)
- Builder.defineMacro("__PTWRITE__");
- if (HasINVPCID)
- Builder.defineMacro("__INVPCID__");
- if (HasENQCMD)
- Builder.defineMacro("__ENQCMD__");
- // Each case falls through to the previous one here.
- switch (SSELevel) {
- case AVX512F:
- Builder.defineMacro("__AVX512F__");
- LLVM_FALLTHROUGH;
- case AVX2:
- Builder.defineMacro("__AVX2__");
- LLVM_FALLTHROUGH;
- case AVX:
- Builder.defineMacro("__AVX__");
- LLVM_FALLTHROUGH;
- case SSE42:
- Builder.defineMacro("__SSE4_2__");
- LLVM_FALLTHROUGH;
- case SSE41:
- Builder.defineMacro("__SSE4_1__");
- LLVM_FALLTHROUGH;
- case SSSE3:
- Builder.defineMacro("__SSSE3__");
- LLVM_FALLTHROUGH;
- case SSE3:
- Builder.defineMacro("__SSE3__");
- LLVM_FALLTHROUGH;
- case SSE2:
- Builder.defineMacro("__SSE2__");
- Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied.
- LLVM_FALLTHROUGH;
- case SSE1:
- Builder.defineMacro("__SSE__");
- Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied.
- LLVM_FALLTHROUGH;
- case NoSSE:
- break;
- }
- if (Opts.MicrosoftExt && getTriple().getArch() == llvm::Triple::x86) {
- switch (SSELevel) {
- case AVX512F:
- case AVX2:
- case AVX:
- case SSE42:
- case SSE41:
- case SSSE3:
- case SSE3:
- case SSE2:
- Builder.defineMacro("_M_IX86_FP", Twine(2));
- break;
- case SSE1:
- Builder.defineMacro("_M_IX86_FP", Twine(1));
- break;
- default:
- Builder.defineMacro("_M_IX86_FP", Twine(0));
- break;
- }
- }
- // Each case falls through to the previous one here.
- switch (MMX3DNowLevel) {
- case AMD3DNowAthlon:
- Builder.defineMacro("__3dNOW_A__");
- LLVM_FALLTHROUGH;
- case AMD3DNow:
- Builder.defineMacro("__3dNOW__");
- LLVM_FALLTHROUGH;
- case MMX:
- Builder.defineMacro("__MMX__");
- LLVM_FALLTHROUGH;
- case NoMMX3DNow:
- break;
- }
- if (CPU >= CK_i486 || CPU == CK_Generic) {
- Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
- Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
- Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
- }
- if (HasCX8)
- Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
- if (HasCX16 && getTriple().getArch() == llvm::Triple::x86_64)
- Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
- if (HasFloat128)
- Builder.defineMacro("__SIZEOF_FLOAT128__", "16");
- }
- bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
- return llvm::StringSwitch<bool>(Name)
- .Case("3dnow", true)
- .Case("3dnowa", true)
- .Case("adx", true)
- .Case("aes", true)
- .Case("avx", true)
- .Case("avx2", true)
- .Case("avx512f", true)
- .Case("avx512cd", true)
- .Case("avx512vpopcntdq", true)
- .Case("avx512vnni", true)
- .Case("avx512bf16", true)
- .Case("avx512er", true)
- .Case("avx512pf", true)
- .Case("avx512dq", true)
- .Case("avx512bitalg", true)
- .Case("avx512bw", true)
- .Case("avx512vl", true)
- .Case("avx512vbmi", true)
- .Case("avx512vbmi2", true)
- .Case("avx512ifma", true)
- .Case("avx512vp2intersect", true)
- .Case("bmi", true)
- .Case("bmi2", true)
- .Case("cldemote", true)
- .Case("clflushopt", true)
- .Case("clwb", true)
- .Case("clzero", true)
- .Case("cx16", true)
- .Case("enqcmd", true)
- .Case("f16c", true)
- .Case("fma", true)
- .Case("fma4", true)
- .Case("fsgsbase", true)
- .Case("fxsr", true)
- .Case("gfni", true)
- .Case("invpcid", true)
- .Case("lwp", true)
- .Case("lzcnt", true)
- .Case("mmx", true)
- .Case("movbe", true)
- .Case("movdiri", true)
- .Case("movdir64b", true)
- .Case("mwaitx", true)
- .Case("pclmul", true)
- .Case("pconfig", true)
- .Case("pku", true)
- .Case("popcnt", true)
- .Case("prefetchwt1", true)
- .Case("prfchw", true)
- .Case("ptwrite", true)
- .Case("rdpid", true)
- .Case("rdrnd", true)
- .Case("rdseed", true)
- .Case("rtm", true)
- .Case("sahf", true)
- .Case("sgx", true)
- .Case("sha", true)
- .Case("shstk", true)
- .Case("sse", true)
- .Case("sse2", true)
- .Case("sse3", true)
- .Case("ssse3", true)
- .Case("sse4", true)
- .Case("sse4.1", true)
- .Case("sse4.2", true)
- .Case("sse4a", true)
- .Case("tbm", true)
- .Case("vaes", true)
- .Case("vpclmulqdq", true)
- .Case("wbnoinvd", true)
- .Case("waitpkg", true)
- .Case("x87", true)
- .Case("xop", true)
- .Case("xsave", true)
- .Case("xsavec", true)
- .Case("xsaves", true)
- .Case("xsaveopt", true)
- .Default(false);
- }
- bool X86TargetInfo::hasFeature(StringRef Feature) const {
- return llvm::StringSwitch<bool>(Feature)
- .Case("adx", HasADX)
- .Case("aes", HasAES)
- .Case("avx", SSELevel >= AVX)
- .Case("avx2", SSELevel >= AVX2)
- .Case("avx512f", SSELevel >= AVX512F)
- .Case("avx512cd", HasAVX512CD)
- .Case("avx512vpopcntdq", HasAVX512VPOPCNTDQ)
- .Case("avx512vnni", HasAVX512VNNI)
- .Case("avx512bf16", HasAVX512BF16)
- .Case("avx512er", HasAVX512ER)
- .Case("avx512pf", HasAVX512PF)
- .Case("avx512dq", HasAVX512DQ)
- .Case("avx512bitalg", HasAVX512BITALG)
- .Case("avx512bw", HasAVX512BW)
- .Case("avx512vl", HasAVX512VL)
- .Case("avx512vbmi", HasAVX512VBMI)
- .Case("avx512vbmi2", HasAVX512VBMI2)
- .Case("avx512ifma", HasAVX512IFMA)
- .Case("avx512vp2intersect", HasAVX512VP2INTERSECT)
- .Case("bmi", HasBMI)
- .Case("bmi2", HasBMI2)
- .Case("cldemote", HasCLDEMOTE)
- .Case("clflushopt", HasCLFLUSHOPT)
- .Case("clwb", HasCLWB)
- .Case("clzero", HasCLZERO)
- .Case("cx8", HasCX8)
- .Case("cx16", HasCX16)
- .Case("enqcmd", HasENQCMD)
- .Case("f16c", HasF16C)
- .Case("fma", HasFMA)
- .Case("fma4", XOPLevel >= FMA4)
- .Case("fsgsbase", HasFSGSBASE)
- .Case("fxsr", HasFXSR)
- .Case("gfni", HasGFNI)
- .Case("invpcid", HasINVPCID)
- .Case("lwp", HasLWP)
- .Case("lzcnt", HasLZCNT)
- .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow)
- .Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon)
- .Case("mmx", MMX3DNowLevel >= MMX)
- .Case("movbe", HasMOVBE)
- .Case("movdiri", HasMOVDIRI)
- .Case("movdir64b", HasMOVDIR64B)
- .Case("mwaitx", HasMWAITX)
- .Case("pclmul", HasPCLMUL)
- .Case("pconfig", HasPCONFIG)
- .Case("pku", HasPKU)
- .Case("popcnt", HasPOPCNT)
- .Case("prefetchwt1", HasPREFETCHWT1)
- .Case("prfchw", HasPRFCHW)
- .Case("ptwrite", HasPTWRITE)
- .Case("rdpid", HasRDPID)
- .Case("rdrnd", HasRDRND)
- .Case("rdseed", HasRDSEED)
- .Case("retpoline-external-thunk", HasRetpolineExternalThunk)
- .Case("rtm", HasRTM)
- .Case("sahf", HasLAHFSAHF)
- .Case("sgx", HasSGX)
- .Case("sha", HasSHA)
- .Case("shstk", HasSHSTK)
- .Case("sse", SSELevel >= SSE1)
- .Case("sse2", SSELevel >= SSE2)
- .Case("sse3", SSELevel >= SSE3)
- .Case("ssse3", SSELevel >= SSSE3)
- .Case("sse4.1", SSELevel >= SSE41)
- .Case("sse4.2", SSELevel >= SSE42)
- .Case("sse4a", XOPLevel >= SSE4A)
- .Case("tbm", HasTBM)
- .Case("vaes", HasVAES)
- .Case("vpclmulqdq", HasVPCLMULQDQ)
- .Case("wbnoinvd", HasWBNOINVD)
- .Case("waitpkg", HasWAITPKG)
- .Case("x86", true)
- .Case("x86_32", getTriple().getArch() == llvm::Triple::x86)
- .Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64)
- .Case("xop", XOPLevel >= XOP)
- .Case("xsave", HasXSAVE)
- .Case("xsavec", HasXSAVEC)
- .Case("xsaves", HasXSAVES)
- .Case("xsaveopt", HasXSAVEOPT)
- .Default(false);
- }
- // We can't use a generic validation scheme for the features accepted here
- // versus subtarget features accepted in the target attribute because the
- // bitfield structure that's initialized in the runtime only supports the
- // below currently rather than the full range of subtarget features. (See
- // X86TargetInfo::hasFeature for a somewhat comprehensive list).
- bool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const {
- return llvm::StringSwitch<bool>(FeatureStr)
- #define X86_FEATURE_COMPAT(VAL, ENUM, STR) .Case(STR, true)
- #include "llvm/Support/X86TargetParser.def"
- .Default(false);
- }
- static llvm::X86::ProcessorFeatures getFeature(StringRef Name) {
- return llvm::StringSwitch<llvm::X86::ProcessorFeatures>(Name)
- #define X86_FEATURE_COMPAT(VAL, ENUM, STR) .Case(STR, llvm::X86::ENUM)
- #include "llvm/Support/X86TargetParser.def"
- ;
- // Note, this function should only be used after ensuring the value is
- // correct, so it asserts if the value is out of range.
- }
- static unsigned getFeaturePriority(llvm::X86::ProcessorFeatures Feat) {
- enum class FeatPriority {
- #define FEATURE(FEAT) FEAT,
- #include "clang/Basic/X86Target.def"
- };
- switch (Feat) {
- #define FEATURE(FEAT) \
- case llvm::X86::FEAT: \
- return static_cast<unsigned>(FeatPriority::FEAT);
- #include "clang/Basic/X86Target.def"
- default:
- llvm_unreachable("No Feature Priority for non-CPUSupports Features");
- }
- }
- unsigned X86TargetInfo::multiVersionSortPriority(StringRef Name) const {
- // Valid CPUs have a 'key feature' that compares just better than its key
- // feature.
- CPUKind Kind = getCPUKind(Name);
- if (Kind != CK_Generic) {
- switch (Kind) {
- default:
- llvm_unreachable(
- "CPU Type without a key feature used in 'target' attribute");
- #define PROC_WITH_FEAT(ENUM, STR, IS64, KEY_FEAT) \
- case CK_##ENUM: \
- return (getFeaturePriority(llvm::X86::KEY_FEAT) << 1) + 1;
- #include "clang/Basic/X86Target.def"
- }
- }
- // Now we know we have a feature, so get its priority and shift it a few so
- // that we have sufficient room for the CPUs (above).
- return getFeaturePriority(getFeature(Name)) << 1;
- }
- bool X86TargetInfo::validateCPUSpecificCPUDispatch(StringRef Name) const {
- return llvm::StringSwitch<bool>(Name)
- #define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, true)
- #define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME) .Case(NEW_NAME, true)
- #include "clang/Basic/X86Target.def"
- .Default(false);
- }
- static StringRef CPUSpecificCPUDispatchNameDealias(StringRef Name) {
- return llvm::StringSwitch<StringRef>(Name)
- #define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME) .Case(NEW_NAME, NAME)
- #include "clang/Basic/X86Target.def"
- .Default(Name);
- }
- char X86TargetInfo::CPUSpecificManglingCharacter(StringRef Name) const {
- return llvm::StringSwitch<char>(CPUSpecificCPUDispatchNameDealias(Name))
- #define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, MANGLING)
- #include "clang/Basic/X86Target.def"
- .Default(0);
- }
- void X86TargetInfo::getCPUSpecificCPUDispatchFeatures(
- StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const {
- StringRef WholeList =
- llvm::StringSwitch<StringRef>(CPUSpecificCPUDispatchNameDealias(Name))
- #define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, FEATURES)
- #include "clang/Basic/X86Target.def"
- .Default("");
- WholeList.split(Features, ',', /*MaxSplit=*/-1, /*KeepEmpty=*/false);
- }
- // We can't use a generic validation scheme for the cpus accepted here
- // versus subtarget cpus accepted in the target attribute because the
- // variables intitialized by the runtime only support the below currently
- // rather than the full range of cpus.
- bool X86TargetInfo::validateCpuIs(StringRef FeatureStr) const {
- return llvm::StringSwitch<bool>(FeatureStr)
- #define X86_VENDOR(ENUM, STRING) .Case(STRING, true)
- #define X86_CPU_TYPE_COMPAT_WITH_ALIAS(ARCHNAME, ENUM, STR, ALIAS) \
- .Cases(STR, ALIAS, true)
- #define X86_CPU_TYPE_COMPAT(ARCHNAME, ENUM, STR) .Case(STR, true)
- #define X86_CPU_SUBTYPE_COMPAT(ARCHNAME, ENUM, STR) .Case(STR, true)
- #include "llvm/Support/X86TargetParser.def"
- .Default(false);
- }
- static unsigned matchAsmCCConstraint(const char *&Name) {
- auto RV = llvm::StringSwitch<unsigned>(Name)
- .Case("@cca", 4)
- .Case("@ccae", 5)
- .Case("@ccb", 4)
- .Case("@ccbe", 5)
- .Case("@ccc", 4)
- .Case("@cce", 4)
- .Case("@ccz", 4)
- .Case("@ccg", 4)
- .Case("@ccge", 5)
- .Case("@ccl", 4)
- .Case("@ccle", 5)
- .Case("@ccna", 5)
- .Case("@ccnae", 6)
- .Case("@ccnb", 5)
- .Case("@ccnbe", 6)
- .Case("@ccnc", 5)
- .Case("@ccne", 5)
- .Case("@ccnz", 5)
- .Case("@ccng", 5)
- .Case("@ccnge", 6)
- .Case("@ccnl", 5)
- .Case("@ccnle", 6)
- .Case("@ccno", 5)
- .Case("@ccnp", 5)
- .Case("@ccns", 5)
- .Case("@cco", 4)
- .Case("@ccp", 4)
- .Case("@ccs", 4)
- .Default(0);
- return RV;
- }
- bool X86TargetInfo::validateAsmConstraint(
- const char *&Name, TargetInfo::ConstraintInfo &Info) const {
- switch (*Name) {
- default:
- return false;
- // Constant constraints.
- case 'e': // 32-bit signed integer constant for use with sign-extending x86_64
- // instructions.
- case 'Z': // 32-bit unsigned integer constant for use with zero-extending
- // x86_64 instructions.
- case 's':
- Info.setRequiresImmediate();
- return true;
- case 'I':
- Info.setRequiresImmediate(0, 31);
- return true;
- case 'J':
- Info.setRequiresImmediate(0, 63);
- return true;
- case 'K':
- Info.setRequiresImmediate(-128, 127);
- return true;
- case 'L':
- Info.setRequiresImmediate({int(0xff), int(0xffff), int(0xffffffff)});
- return true;
- case 'M':
- Info.setRequiresImmediate(0, 3);
- return true;
- case 'N':
- Info.setRequiresImmediate(0, 255);
- return true;
- case 'O':
- Info.setRequiresImmediate(0, 127);
- return true;
- // Register constraints.
- case 'Y': // 'Y' is the first character for several 2-character constraints.
- // Shift the pointer to the second character of the constraint.
- Name++;
- switch (*Name) {
- default:
- return false;
- case 'z':
- case '0': // First SSE register.
- case '2':
- case 't': // Any SSE register, when SSE2 is enabled.
- case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled.
- case 'm': // Any MMX register, when inter-unit moves enabled.
- case 'k': // AVX512 arch mask registers: k1-k7.
- Info.setAllowsRegister();
- return true;
- }
- case 'f': // Any x87 floating point stack register.
- // Constraint 'f' cannot be used for output operands.
- if (Info.ConstraintStr[0] == '=')
- return false;
- Info.setAllowsRegister();
- return true;
- case 'a': // eax.
- case 'b': // ebx.
- case 'c': // ecx.
- case 'd': // edx.
- case 'S': // esi.
- case 'D': // edi.
- case 'A': // edx:eax.
- case 't': // Top of floating point stack.
- case 'u': // Second from top of floating point stack.
- case 'q': // Any register accessible as [r]l: a, b, c, and d.
- case 'y': // Any MMX register.
- case 'v': // Any {X,Y,Z}MM register (Arch & context dependent)
- case 'x': // Any SSE register.
- case 'k': // Any AVX512 mask register (same as Yk, additionally allows k0
- // for intermideate k reg operations).
- case 'Q': // Any register accessible as [r]h: a, b, c, and d.
- case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
- case 'l': // "Index" registers: any general register that can be used as an
- // index in a base+index memory access.
- Info.setAllowsRegister();
- return true;
- // Floating point constant constraints.
- case 'C': // SSE floating point constant.
- case 'G': // x87 floating point constant.
- return true;
- case '@':
- // CC condition changes.
- if (auto Len = matchAsmCCConstraint(Name)) {
- Name += Len - 1;
- Info.setAllowsRegister();
- return true;
- }
- return false;
- }
- }
- bool X86TargetInfo::validateOutputSize(StringRef Constraint,
- unsigned Size) const {
- // Strip off constraint modifiers.
- while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
- Constraint = Constraint.substr(1);
- return validateOperandSize(Constraint, Size);
- }
- bool X86TargetInfo::validateInputSize(StringRef Constraint,
- unsigned Size) const {
- return validateOperandSize(Constraint, Size);
- }
- bool X86TargetInfo::validateOperandSize(StringRef Constraint,
- unsigned Size) const {
- switch (Constraint[0]) {
- default:
- break;
- case 'k':
- // Registers k0-k7 (AVX512) size limit is 64 bit.
- case 'y':
- return Size <= 64;
- case 'f':
- case 't':
- case 'u':
- return Size <= 128;
- case 'Y':
- // 'Y' is the first character for several 2-character constraints.
- switch (Constraint[1]) {
- default:
- return false;
- case 'm':
- // 'Ym' is synonymous with 'y'.
- case 'k':
- return Size <= 64;
- case 'z':
- case '0':
- // XMM0
- if (SSELevel >= SSE1)
- return Size <= 128U;
- return false;
- case 'i':
- case 't':
- case '2':
- // 'Yi','Yt','Y2' are synonymous with 'x' when SSE2 is enabled.
- if (SSELevel < SSE2)
- return false;
- break;
- }
- LLVM_FALLTHROUGH;
- case 'v':
- case 'x':
- if (SSELevel >= AVX512F)
- // 512-bit zmm registers can be used if target supports AVX512F.
- return Size <= 512U;
- else if (SSELevel >= AVX)
- // 256-bit ymm registers can be used if target supports AVX.
- return Size <= 256U;
- return Size <= 128U;
- }
- return true;
- }
- std::string X86TargetInfo::convertConstraint(const char *&Constraint) const {
- switch (*Constraint) {
- case '@':
- if (auto Len = matchAsmCCConstraint(Constraint)) {
- std::string Converted = "{" + std::string(Constraint, Len) + "}";
- Constraint += Len - 1;
- return Converted;
- }
- return std::string(1, *Constraint);
- case 'a':
- return std::string("{ax}");
- case 'b':
- return std::string("{bx}");
- case 'c':
- return std::string("{cx}");
- case 'd':
- return std::string("{dx}");
- case 'S':
- return std::string("{si}");
- case 'D':
- return std::string("{di}");
- case 'p': // address
- return std::string("im");
- case 't': // top of floating point stack.
- return std::string("{st}");
- case 'u': // second from top of floating point stack.
- return std::string("{st(1)}"); // second from top of floating point stack.
- case 'Y':
- switch (Constraint[1]) {
- default:
- // Break from inner switch and fall through (copy single char),
- // continue parsing after copying the current constraint into
- // the return string.
- break;
- case 'k':
- case 'm':
- case 'i':
- case 't':
- case 'z':
- case '0':
- case '2':
- // "^" hints llvm that this is a 2 letter constraint.
- // "Constraint++" is used to promote the string iterator
- // to the next constraint.
- return std::string("^") + std::string(Constraint++, 2);
- }
- LLVM_FALLTHROUGH;
- default:
- return std::string(1, *Constraint);
- }
- }
- bool X86TargetInfo::checkCPUKind(CPUKind Kind) const {
- // Perform any per-CPU checks necessary to determine if this CPU is
- // acceptable.
- switch (Kind) {
- case CK_Generic:
- // No processor selected!
- return false;
- #define PROC(ENUM, STRING, IS64BIT) \
- case CK_##ENUM: \
- return IS64BIT || getTriple().getArch() == llvm::Triple::x86;
- #include "clang/Basic/X86Target.def"
- }
- llvm_unreachable("Unhandled CPU kind");
- }
- void X86TargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
- #define PROC(ENUM, STRING, IS64BIT) \
- if (IS64BIT || getTriple().getArch() == llvm::Triple::x86) \
- Values.emplace_back(STRING);
- // For aliases we need to lookup the CPUKind to check get the 64-bit ness.
- #define PROC_ALIAS(ENUM, ALIAS) \
- if (checkCPUKind(CK_##ENUM)) \
- Values.emplace_back(ALIAS);
- #include "clang/Basic/X86Target.def"
- }
- X86TargetInfo::CPUKind X86TargetInfo::getCPUKind(StringRef CPU) const {
- return llvm::StringSwitch<CPUKind>(CPU)
- #define PROC(ENUM, STRING, IS64BIT) .Case(STRING, CK_##ENUM)
- #define PROC_ALIAS(ENUM, ALIAS) .Case(ALIAS, CK_##ENUM)
- #include "clang/Basic/X86Target.def"
- .Default(CK_Generic);
- }
- ArrayRef<const char *> X86TargetInfo::getGCCRegNames() const {
- return llvm::makeArrayRef(GCCRegNames);
- }
- ArrayRef<TargetInfo::AddlRegName> X86TargetInfo::getGCCAddlRegNames() const {
- return llvm::makeArrayRef(AddlRegNames);
- }
- ArrayRef<Builtin::Info> X86_32TargetInfo::getTargetBuiltins() const {
- return llvm::makeArrayRef(BuiltinInfoX86, clang::X86::LastX86CommonBuiltin -
- Builtin::FirstTSBuiltin + 1);
- }
- ArrayRef<Builtin::Info> X86_64TargetInfo::getTargetBuiltins() const {
- return llvm::makeArrayRef(BuiltinInfoX86,
- X86::LastTSBuiltin - Builtin::FirstTSBuiltin);
- }
|