| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| //===------- Targets.h - Declare target feature support -------------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file declares things required for construction of a TargetInfo object | ||
| // from a target triple. Typically individual targets will need to include from | ||
| // here in order to get these functions if required. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_H | ||
| #define LLVM_CLANG_LIB_BASIC_TARGETS_H | ||
|
|
||
| #include "clang/Basic/LangOptions.h" | ||
| #include "clang/Basic/MacroBuilder.h" | ||
| #include "clang/Basic/TargetInfo.h" | ||
| #include "llvm/ADT/StringRef.h" | ||
|
|
||
| namespace clang { | ||
| namespace targets { | ||
|
|
||
| LLVM_LIBRARY_VISIBILITY | ||
| clang::TargetInfo *AllocateTarget(const llvm::Triple &Triple, | ||
| const clang::TargetOptions &Opts); | ||
|
|
||
| /// DefineStd - Define a macro name and standard variants. For example if | ||
| /// MacroName is "unix", then this will define "__unix", "__unix__", and "unix" | ||
| /// when in GNU mode. | ||
| LLVM_LIBRARY_VISIBILITY | ||
| void DefineStd(clang::MacroBuilder &Builder, llvm::StringRef MacroName, | ||
| const clang::LangOptions &Opts); | ||
|
|
||
| LLVM_LIBRARY_VISIBILITY | ||
| void defineCPUMacros(clang::MacroBuilder &Builder, llvm::StringRef CPUName, | ||
| bool Tuning = true); | ||
|
|
||
| LLVM_LIBRARY_VISIBILITY | ||
| void addMinGWDefines(const clang::LangOptions &Opts, | ||
| clang::MacroBuilder &Builder); | ||
| } // namespace targets | ||
| } // namespace clang | ||
| #endif // LLVM_CLANG_LIB_BASIC_TARGETS_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| //===--- AArch64.cpp - Implement AArch64 target feature support -----------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file implements AArch64 TargetInfo objects. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "AArch64.h" | ||
| #include "clang/Basic/TargetBuiltins.h" | ||
| #include "clang/Basic/TargetInfo.h" | ||
| #include "llvm/ADT/ArrayRef.h" | ||
|
|
||
| using namespace clang; | ||
| using namespace clang::targets; | ||
|
|
||
| const char *const AArch64TargetInfo::GCCRegNames[] = { | ||
| // 32-bit Integer registers | ||
| "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11", | ||
| "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22", | ||
| "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp", | ||
|
|
||
| // 64-bit Integer registers | ||
| "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", | ||
| "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", | ||
| "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp", | ||
|
|
||
| // 32-bit floating point regsisters | ||
| "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", | ||
| "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22", | ||
| "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", | ||
|
|
||
| // 64-bit floating point regsisters | ||
| "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11", | ||
| "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22", | ||
| "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", | ||
|
|
||
| // Vector registers | ||
| "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", | ||
| "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", | ||
| "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31" | ||
| }; | ||
|
|
||
| ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const { | ||
| return llvm::makeArrayRef(GCCRegNames); | ||
| } | ||
|
|
||
| const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = { | ||
| {{"w31"}, "wsp"}, {{"x29"}, "fp"}, {{"x30"}, "lr"}, {{"x31"}, "sp"}, | ||
| // The S/D/Q and W/X registers overlap, but aren't really aliases; we | ||
| // don't want to substitute one of these for a different-sized one. | ||
| }; | ||
|
|
||
| ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const { | ||
| return llvm::makeArrayRef(GCCRegAliases); | ||
| } | ||
|
|
||
| const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = { | ||
| #define BUILTIN(ID, TYPE, ATTRS) \ | ||
| {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, | ||
| #include "clang/Basic/BuiltinsNEON.def" | ||
|
|
||
| #define BUILTIN(ID, TYPE, ATTRS) \ | ||
| {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, | ||
| #include "clang/Basic/BuiltinsAArch64.def" | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,356 @@ | ||
| //===--- AMDGPU.cpp - Implement AMDGPU target feature support -------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file implements AMDGPU TargetInfo objects. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "AMDGPU.h" | ||
| #include "clang/Basic/Builtins.h" | ||
| #include "clang/Basic/LangOptions.h" | ||
| #include "clang/Basic/MacroBuilder.h" | ||
| #include "clang/Basic/TargetBuiltins.h" | ||
| #include "clang/Frontend/CodeGenOptions.h" | ||
| #include "llvm/ADT/StringSwitch.h" | ||
|
|
||
| using namespace clang; | ||
| using namespace clang::targets; | ||
|
|
||
| namespace clang { | ||
| namespace targets { | ||
|
|
||
| // If you edit the description strings, make sure you update | ||
| // getPointerWidthV(). | ||
|
|
||
| static const char *const DataLayoutStringR600 = | ||
| "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128" | ||
| "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"; | ||
|
|
||
| static const char *const DataLayoutStringSIPrivateIsZero = | ||
| "e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32" | ||
| "-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128" | ||
| "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"; | ||
|
|
||
| static const char *const DataLayoutStringSIGenericIsZero = | ||
| "e-p:64:64-p1:64:64-p2:64:64-p3:32:32-p4:32:32-p5:32:32" | ||
| "-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128" | ||
| "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-A5"; | ||
|
|
||
| static const LangAS::Map AMDGPUPrivIsZeroDefIsGenMap = { | ||
| 4, // Default | ||
| 1, // opencl_global | ||
| 3, // opencl_local | ||
| 2, // opencl_constant | ||
| 4, // opencl_generic | ||
| 1, // cuda_device | ||
| 2, // cuda_constant | ||
| 3 // cuda_shared | ||
| }; | ||
|
|
||
| static const LangAS::Map AMDGPUGenIsZeroDefIsGenMap = { | ||
| 0, // Default | ||
| 1, // opencl_global | ||
| 3, // opencl_local | ||
| 2, // opencl_constant | ||
| 0, // opencl_generic | ||
| 1, // cuda_device | ||
| 2, // cuda_constant | ||
| 3 // cuda_shared | ||
| }; | ||
|
|
||
| static const LangAS::Map AMDGPUPrivIsZeroDefIsPrivMap = { | ||
| 0, // Default | ||
| 1, // opencl_global | ||
| 3, // opencl_local | ||
| 2, // opencl_constant | ||
| 4, // opencl_generic | ||
| 1, // cuda_device | ||
| 2, // cuda_constant | ||
| 3 // cuda_shared | ||
| }; | ||
|
|
||
| static const LangAS::Map AMDGPUGenIsZeroDefIsPrivMap = { | ||
| 5, // Default | ||
| 1, // opencl_global | ||
| 3, // opencl_local | ||
| 2, // opencl_constant | ||
| 0, // opencl_generic | ||
| 1, // cuda_device | ||
| 2, // cuda_constant | ||
| 3 // cuda_shared | ||
| }; | ||
| } // namespace targets | ||
| } // namespace clang | ||
|
|
||
| const Builtin::Info AMDGPUTargetInfo::BuiltinInfo[] = { | ||
| #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}, | ||
| #include "clang/Basic/BuiltinsAMDGPU.def" | ||
| }; | ||
|
|
||
| const char *const AMDGPUTargetInfo::GCCRegNames[] = { | ||
| "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", | ||
| "v9", "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", | ||
| "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", | ||
| "v27", "v28", "v29", "v30", "v31", "v32", "v33", "v34", "v35", | ||
| "v36", "v37", "v38", "v39", "v40", "v41", "v42", "v43", "v44", | ||
| "v45", "v46", "v47", "v48", "v49", "v50", "v51", "v52", "v53", | ||
| "v54", "v55", "v56", "v57", "v58", "v59", "v60", "v61", "v62", | ||
| "v63", "v64", "v65", "v66", "v67", "v68", "v69", "v70", "v71", | ||
| "v72", "v73", "v74", "v75", "v76", "v77", "v78", "v79", "v80", | ||
| "v81", "v82", "v83", "v84", "v85", "v86", "v87", "v88", "v89", | ||
| "v90", "v91", "v92", "v93", "v94", "v95", "v96", "v97", "v98", | ||
| "v99", "v100", "v101", "v102", "v103", "v104", "v105", "v106", "v107", | ||
| "v108", "v109", "v110", "v111", "v112", "v113", "v114", "v115", "v116", | ||
| "v117", "v118", "v119", "v120", "v121", "v122", "v123", "v124", "v125", | ||
| "v126", "v127", "v128", "v129", "v130", "v131", "v132", "v133", "v134", | ||
| "v135", "v136", "v137", "v138", "v139", "v140", "v141", "v142", "v143", | ||
| "v144", "v145", "v146", "v147", "v148", "v149", "v150", "v151", "v152", | ||
| "v153", "v154", "v155", "v156", "v157", "v158", "v159", "v160", "v161", | ||
| "v162", "v163", "v164", "v165", "v166", "v167", "v168", "v169", "v170", | ||
| "v171", "v172", "v173", "v174", "v175", "v176", "v177", "v178", "v179", | ||
| "v180", "v181", "v182", "v183", "v184", "v185", "v186", "v187", "v188", | ||
| "v189", "v190", "v191", "v192", "v193", "v194", "v195", "v196", "v197", | ||
| "v198", "v199", "v200", "v201", "v202", "v203", "v204", "v205", "v206", | ||
| "v207", "v208", "v209", "v210", "v211", "v212", "v213", "v214", "v215", | ||
| "v216", "v217", "v218", "v219", "v220", "v221", "v222", "v223", "v224", | ||
| "v225", "v226", "v227", "v228", "v229", "v230", "v231", "v232", "v233", | ||
| "v234", "v235", "v236", "v237", "v238", "v239", "v240", "v241", "v242", | ||
| "v243", "v244", "v245", "v246", "v247", "v248", "v249", "v250", "v251", | ||
| "v252", "v253", "v254", "v255", "s0", "s1", "s2", "s3", "s4", | ||
| "s5", "s6", "s7", "s8", "s9", "s10", "s11", "s12", "s13", | ||
| "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22", | ||
| "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", | ||
| "s32", "s33", "s34", "s35", "s36", "s37", "s38", "s39", "s40", | ||
| "s41", "s42", "s43", "s44", "s45", "s46", "s47", "s48", "s49", | ||
| "s50", "s51", "s52", "s53", "s54", "s55", "s56", "s57", "s58", | ||
| "s59", "s60", "s61", "s62", "s63", "s64", "s65", "s66", "s67", | ||
| "s68", "s69", "s70", "s71", "s72", "s73", "s74", "s75", "s76", | ||
| "s77", "s78", "s79", "s80", "s81", "s82", "s83", "s84", "s85", | ||
| "s86", "s87", "s88", "s89", "s90", "s91", "s92", "s93", "s94", | ||
| "s95", "s96", "s97", "s98", "s99", "s100", "s101", "s102", "s103", | ||
| "s104", "s105", "s106", "s107", "s108", "s109", "s110", "s111", "s112", | ||
| "s113", "s114", "s115", "s116", "s117", "s118", "s119", "s120", "s121", | ||
| "s122", "s123", "s124", "s125", "s126", "s127", "exec", "vcc", "scc", | ||
| "m0", "flat_scratch", "exec_lo", "exec_hi", "vcc_lo", "vcc_hi", | ||
| "flat_scratch_lo", "flat_scratch_hi" | ||
| }; | ||
|
|
||
| ArrayRef<const char *> AMDGPUTargetInfo::getGCCRegNames() const { | ||
| return llvm::makeArrayRef(GCCRegNames); | ||
| } | ||
|
|
||
| bool AMDGPUTargetInfo::initFeatureMap( | ||
| llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, | ||
| const std::vector<std::string> &FeatureVec) const { | ||
|
|
||
| // XXX - What does the member GPU mean if device name string passed here? | ||
| if (getTriple().getArch() == llvm::Triple::amdgcn) { | ||
| if (CPU.empty()) | ||
| CPU = "tahiti"; | ||
|
|
||
| switch (parseAMDGCNName(CPU)) { | ||
| case GK_GFX6: | ||
| case GK_GFX7: | ||
| break; | ||
|
|
||
| case GK_GFX9: | ||
| Features["gfx9-insts"] = true; | ||
| LLVM_FALLTHROUGH; | ||
| case GK_GFX8: | ||
| Features["s-memrealtime"] = true; | ||
| Features["16-bit-insts"] = true; | ||
| Features["dpp"] = true; | ||
| break; | ||
|
|
||
| case GK_NONE: | ||
| return false; | ||
| default: | ||
| llvm_unreachable("unhandled subtarget"); | ||
| } | ||
| } else { | ||
| if (CPU.empty()) | ||
| CPU = "r600"; | ||
|
|
||
| switch (parseR600Name(CPU)) { | ||
| case GK_R600: | ||
| case GK_R700: | ||
| case GK_EVERGREEN: | ||
| case GK_NORTHERN_ISLANDS: | ||
| break; | ||
| case GK_R600_DOUBLE_OPS: | ||
| case GK_R700_DOUBLE_OPS: | ||
| case GK_EVERGREEN_DOUBLE_OPS: | ||
| case GK_CAYMAN: | ||
| Features["fp64"] = true; | ||
| break; | ||
| case GK_NONE: | ||
| return false; | ||
| default: | ||
| llvm_unreachable("unhandled subtarget"); | ||
| } | ||
| } | ||
|
|
||
| return TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec); | ||
| } | ||
|
|
||
| void AMDGPUTargetInfo::adjustTargetOptions(const CodeGenOptions &CGOpts, | ||
| TargetOptions &TargetOpts) const { | ||
| bool hasFP32Denormals = false; | ||
| bool hasFP64Denormals = false; | ||
| for (auto &I : TargetOpts.FeaturesAsWritten) { | ||
| if (I == "+fp32-denormals" || I == "-fp32-denormals") | ||
| hasFP32Denormals = true; | ||
| if (I == "+fp64-fp16-denormals" || I == "-fp64-fp16-denormals") | ||
| hasFP64Denormals = true; | ||
| } | ||
| if (!hasFP32Denormals) | ||
| TargetOpts.Features.push_back( | ||
| (Twine(hasFullSpeedFMAF32(TargetOpts.CPU) && !CGOpts.FlushDenorm | ||
| ? '+' | ||
| : '-') + | ||
| Twine("fp32-denormals")) | ||
| .str()); | ||
| // Always do not flush fp64 or fp16 denorms. | ||
| if (!hasFP64Denormals && hasFP64) | ||
| TargetOpts.Features.push_back("+fp64-fp16-denormals"); | ||
| } | ||
|
|
||
| AMDGPUTargetInfo::GPUKind AMDGPUTargetInfo::parseR600Name(StringRef Name) { | ||
| return llvm::StringSwitch<GPUKind>(Name) | ||
| .Case("r600", GK_R600) | ||
| .Case("rv610", GK_R600) | ||
| .Case("rv620", GK_R600) | ||
| .Case("rv630", GK_R600) | ||
| .Case("rv635", GK_R600) | ||
| .Case("rs780", GK_R600) | ||
| .Case("rs880", GK_R600) | ||
| .Case("rv670", GK_R600_DOUBLE_OPS) | ||
| .Case("rv710", GK_R700) | ||
| .Case("rv730", GK_R700) | ||
| .Case("rv740", GK_R700_DOUBLE_OPS) | ||
| .Case("rv770", GK_R700_DOUBLE_OPS) | ||
| .Case("palm", GK_EVERGREEN) | ||
| .Case("cedar", GK_EVERGREEN) | ||
| .Case("sumo", GK_EVERGREEN) | ||
| .Case("sumo2", GK_EVERGREEN) | ||
| .Case("redwood", GK_EVERGREEN) | ||
| .Case("juniper", GK_EVERGREEN) | ||
| .Case("hemlock", GK_EVERGREEN_DOUBLE_OPS) | ||
| .Case("cypress", GK_EVERGREEN_DOUBLE_OPS) | ||
| .Case("barts", GK_NORTHERN_ISLANDS) | ||
| .Case("turks", GK_NORTHERN_ISLANDS) | ||
| .Case("caicos", GK_NORTHERN_ISLANDS) | ||
| .Case("cayman", GK_CAYMAN) | ||
| .Case("aruba", GK_CAYMAN) | ||
| .Default(GK_NONE); | ||
| } | ||
|
|
||
| AMDGPUTargetInfo::GPUKind AMDGPUTargetInfo::parseAMDGCNName(StringRef Name) { | ||
| return llvm::StringSwitch<GPUKind>(Name) | ||
| .Case("tahiti", GK_GFX6) | ||
| .Case("pitcairn", GK_GFX6) | ||
| .Case("verde", GK_GFX6) | ||
| .Case("oland", GK_GFX6) | ||
| .Case("hainan", GK_GFX6) | ||
| .Case("bonaire", GK_GFX7) | ||
| .Case("kabini", GK_GFX7) | ||
| .Case("kaveri", GK_GFX7) | ||
| .Case("hawaii", GK_GFX7) | ||
| .Case("mullins", GK_GFX7) | ||
| .Case("gfx700", GK_GFX7) | ||
| .Case("gfx701", GK_GFX7) | ||
| .Case("gfx702", GK_GFX7) | ||
| .Case("tonga", GK_GFX8) | ||
| .Case("iceland", GK_GFX8) | ||
| .Case("carrizo", GK_GFX8) | ||
| .Case("fiji", GK_GFX8) | ||
| .Case("stoney", GK_GFX8) | ||
| .Case("polaris10", GK_GFX8) | ||
| .Case("polaris11", GK_GFX8) | ||
| .Case("gfx800", GK_GFX8) | ||
| .Case("gfx801", GK_GFX8) | ||
| .Case("gfx802", GK_GFX8) | ||
| .Case("gfx803", GK_GFX8) | ||
| .Case("gfx804", GK_GFX8) | ||
| .Case("gfx810", GK_GFX8) | ||
| .Case("gfx900", GK_GFX9) | ||
| .Case("gfx901", GK_GFX9) | ||
| .Default(GK_NONE); | ||
| } | ||
|
|
||
| void AMDGPUTargetInfo::setAddressSpaceMap(bool DefaultIsPrivate) { | ||
| if (isGenericZero(getTriple())) { | ||
| AddrSpaceMap = DefaultIsPrivate ? &AMDGPUGenIsZeroDefIsPrivMap | ||
| : &AMDGPUGenIsZeroDefIsGenMap; | ||
| } else { | ||
| AddrSpaceMap = DefaultIsPrivate ? &AMDGPUPrivIsZeroDefIsPrivMap | ||
| : &AMDGPUPrivIsZeroDefIsGenMap; | ||
| } | ||
| } | ||
|
|
||
| AMDGPUTargetInfo::AMDGPUTargetInfo(const llvm::Triple &Triple, | ||
| const TargetOptions &Opts) | ||
| : TargetInfo(Triple), GPU(isAMDGCN(Triple) ? GK_GFX6 : GK_R600), | ||
| hasFP64(false), hasFMAF(false), hasLDEXPF(false), | ||
| AS(isGenericZero(Triple)) { | ||
| if (getTriple().getArch() == llvm::Triple::amdgcn) { | ||
| hasFP64 = true; | ||
| hasFMAF = true; | ||
| hasLDEXPF = true; | ||
| } | ||
| auto IsGenericZero = isGenericZero(Triple); | ||
| resetDataLayout(getTriple().getArch() == llvm::Triple::amdgcn | ||
| ? (IsGenericZero ? DataLayoutStringSIGenericIsZero | ||
| : DataLayoutStringSIPrivateIsZero) | ||
| : DataLayoutStringR600); | ||
| assert(DataLayout->getAllocaAddrSpace() == AS.Private); | ||
|
|
||
| setAddressSpaceMap(Triple.getOS() == llvm::Triple::Mesa3D || | ||
| Triple.getEnvironment() == llvm::Triple::OpenCL || | ||
| Triple.getEnvironmentName() == "amdgizcl" || | ||
| !isAMDGCN(Triple)); | ||
| UseAddrSpaceMapMangling = true; | ||
|
|
||
| // Set pointer width and alignment for target address space 0. | ||
| PointerWidth = PointerAlign = DataLayout->getPointerSizeInBits(); | ||
| if (getMaxPointerWidth() == 64) { | ||
| LongWidth = LongAlign = 64; | ||
| SizeType = UnsignedLong; | ||
| PtrDiffType = SignedLong; | ||
| IntPtrType = SignedLong; | ||
| } | ||
| } | ||
|
|
||
| void AMDGPUTargetInfo::adjust(LangOptions &Opts) { | ||
| TargetInfo::adjust(Opts); | ||
| setAddressSpaceMap(Opts.OpenCL || !isAMDGCN(getTriple())); | ||
| } | ||
|
|
||
| ArrayRef<Builtin::Info> AMDGPUTargetInfo::getTargetBuiltins() const { | ||
| return llvm::makeArrayRef(BuiltinInfo, clang::AMDGPU::LastTSBuiltin - | ||
| Builtin::FirstTSBuiltin); | ||
| } | ||
|
|
||
| void AMDGPUTargetInfo::getTargetDefines(const LangOptions &Opts, | ||
| MacroBuilder &Builder) const { | ||
| if (getTriple().getArch() == llvm::Triple::amdgcn) | ||
| Builder.defineMacro("__AMDGCN__"); | ||
| else | ||
| Builder.defineMacro("__R600__"); | ||
|
|
||
| if (hasFMAF) | ||
| Builder.defineMacro("__HAS_FMAF__"); | ||
| if (hasLDEXPF) | ||
| Builder.defineMacro("__HAS_LDEXPF__"); | ||
| if (hasFP64) | ||
| Builder.defineMacro("__HAS_FP64__"); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,244 @@ | ||
| //===--- AMDGPU.h - Declare AMDGPU target feature support -------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file declares AMDGPU TargetInfo objects. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_AMDGPU_H | ||
| #define LLVM_CLANG_LIB_BASIC_TARGETS_AMDGPU_H | ||
|
|
||
| #include "clang/Basic/TargetInfo.h" | ||
| #include "clang/Basic/TargetOptions.h" | ||
| #include "llvm/ADT/Triple.h" | ||
| #include "llvm/Support/Compiler.h" | ||
|
|
||
| namespace clang { | ||
| namespace targets { | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo { | ||
|
|
||
| static const Builtin::Info BuiltinInfo[]; | ||
| static const char *const GCCRegNames[]; | ||
|
|
||
| struct LLVM_LIBRARY_VISIBILITY AddrSpace { | ||
| unsigned Generic, Global, Local, Constant, Private; | ||
| AddrSpace(bool IsGenericZero_ = false) { | ||
| if (IsGenericZero_) { | ||
| Generic = 0; | ||
| Global = 1; | ||
| Local = 3; | ||
| Constant = 2; | ||
| Private = 5; | ||
| } else { | ||
| Generic = 4; | ||
| Global = 1; | ||
| Local = 3; | ||
| Constant = 2; | ||
| Private = 0; | ||
| } | ||
| } | ||
| }; | ||
|
|
||
| /// \brief The GPU profiles supported by the AMDGPU target. | ||
| enum GPUKind { | ||
| GK_NONE, | ||
| GK_R600, | ||
| GK_R600_DOUBLE_OPS, | ||
| GK_R700, | ||
| GK_R700_DOUBLE_OPS, | ||
| GK_EVERGREEN, | ||
| GK_EVERGREEN_DOUBLE_OPS, | ||
| GK_NORTHERN_ISLANDS, | ||
| GK_CAYMAN, | ||
| GK_GFX6, | ||
| GK_GFX7, | ||
| GK_GFX8, | ||
| GK_GFX9 | ||
| } GPU; | ||
|
|
||
| bool hasFP64 : 1; | ||
| bool hasFMAF : 1; | ||
| bool hasLDEXPF : 1; | ||
| const AddrSpace AS; | ||
|
|
||
| static bool hasFullSpeedFMAF32(StringRef GPUName) { | ||
| return parseAMDGCNName(GPUName) >= GK_GFX9; | ||
| } | ||
|
|
||
| static bool isAMDGCN(const llvm::Triple &TT) { | ||
| return TT.getArch() == llvm::Triple::amdgcn; | ||
| } | ||
|
|
||
| static bool isGenericZero(const llvm::Triple &TT) { | ||
| return TT.getEnvironmentName() == "amdgiz" || | ||
| TT.getEnvironmentName() == "amdgizcl"; | ||
| } | ||
|
|
||
| public: | ||
| AMDGPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts); | ||
|
|
||
| void setAddressSpaceMap(bool DefaultIsPrivate); | ||
|
|
||
| void adjust(LangOptions &Opts) override; | ||
|
|
||
| uint64_t getPointerWidthV(unsigned AddrSpace) const override { | ||
| if (GPU <= GK_CAYMAN) | ||
| return 32; | ||
|
|
||
| if (AddrSpace == AS.Private || AddrSpace == AS.Local) { | ||
| return 32; | ||
| } | ||
| return 64; | ||
| } | ||
|
|
||
| uint64_t getPointerAlignV(unsigned AddrSpace) const override { | ||
| return getPointerWidthV(AddrSpace); | ||
| } | ||
|
|
||
| uint64_t getMaxPointerWidth() const override { | ||
| return getTriple().getArch() == llvm::Triple::amdgcn ? 64 : 32; | ||
| } | ||
|
|
||
| const char *getClobbers() const override { return ""; } | ||
|
|
||
| ArrayRef<const char *> getGCCRegNames() const override; | ||
|
|
||
| ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { | ||
| return None; | ||
| } | ||
|
|
||
| bool validateAsmConstraint(const char *&Name, | ||
| TargetInfo::ConstraintInfo &Info) const override { | ||
| switch (*Name) { | ||
| default: | ||
| break; | ||
| case 'v': // vgpr | ||
| case 's': // sgpr | ||
| Info.setAllowsRegister(); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| bool | ||
| initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, | ||
| StringRef CPU, | ||
| const std::vector<std::string> &FeatureVec) const override; | ||
|
|
||
| void adjustTargetOptions(const CodeGenOptions &CGOpts, | ||
| TargetOptions &TargetOpts) const override; | ||
|
|
||
| ArrayRef<Builtin::Info> getTargetBuiltins() const override; | ||
|
|
||
| void getTargetDefines(const LangOptions &Opts, | ||
| MacroBuilder &Builder) const override; | ||
|
|
||
| BuiltinVaListKind getBuiltinVaListKind() const override { | ||
| return TargetInfo::CharPtrBuiltinVaList; | ||
| } | ||
|
|
||
| static GPUKind parseR600Name(StringRef Name); | ||
|
|
||
| static GPUKind parseAMDGCNName(StringRef Name); | ||
|
|
||
| bool isValidCPUName(StringRef Name) const override { | ||
| if (getTriple().getArch() == llvm::Triple::amdgcn) | ||
| return GK_NONE != parseAMDGCNName(Name); | ||
| else | ||
| return GK_NONE != parseR600Name(Name); | ||
| } | ||
|
|
||
| bool setCPU(const std::string &Name) override { | ||
| if (getTriple().getArch() == llvm::Triple::amdgcn) | ||
| GPU = parseAMDGCNName(Name); | ||
| else | ||
| GPU = parseR600Name(Name); | ||
|
|
||
| return GPU != GK_NONE; | ||
| } | ||
|
|
||
| void setSupportedOpenCLOpts() override { | ||
| auto &Opts = getSupportedOpenCLOpts(); | ||
| Opts.support("cl_clang_storage_class_specifiers"); | ||
| Opts.support("cl_khr_icd"); | ||
|
|
||
| if (hasFP64) | ||
| Opts.support("cl_khr_fp64"); | ||
| if (GPU >= GK_EVERGREEN) { | ||
| Opts.support("cl_khr_byte_addressable_store"); | ||
| Opts.support("cl_khr_global_int32_base_atomics"); | ||
| Opts.support("cl_khr_global_int32_extended_atomics"); | ||
| Opts.support("cl_khr_local_int32_base_atomics"); | ||
| Opts.support("cl_khr_local_int32_extended_atomics"); | ||
| } | ||
| if (GPU >= GK_GFX6) { | ||
| Opts.support("cl_khr_fp16"); | ||
| Opts.support("cl_khr_int64_base_atomics"); | ||
| Opts.support("cl_khr_int64_extended_atomics"); | ||
| Opts.support("cl_khr_mipmap_image"); | ||
| Opts.support("cl_khr_subgroups"); | ||
| Opts.support("cl_khr_3d_image_writes"); | ||
| Opts.support("cl_amd_media_ops"); | ||
| Opts.support("cl_amd_media_ops2"); | ||
| } | ||
| } | ||
|
|
||
| LangAS::ID getOpenCLImageAddrSpace() const override { | ||
| return LangAS::opencl_constant; | ||
| } | ||
|
|
||
| llvm::Optional<unsigned> getConstantAddressSpace() const override { | ||
| return LangAS::FirstTargetAddressSpace + AS.Constant; | ||
| } | ||
|
|
||
| /// \returns Target specific vtbl ptr address space. | ||
| unsigned getVtblPtrAddressSpace() const override { return AS.Constant; } | ||
|
|
||
| /// \returns If a target requires an address within a target specific address | ||
| /// space \p AddressSpace to be converted in order to be used, then return the | ||
| /// corresponding target specific DWARF address space. | ||
| /// | ||
| /// \returns Otherwise return None and no conversion will be emitted in the | ||
| /// DWARF. | ||
| Optional<unsigned> | ||
| getDWARFAddressSpace(unsigned AddressSpace) const override { | ||
| const unsigned DWARF_Private = 1; | ||
| const unsigned DWARF_Local = 2; | ||
| if (AddressSpace == AS.Private) { | ||
| return DWARF_Private; | ||
| } else if (AddressSpace == AS.Local) { | ||
| return DWARF_Local; | ||
| } else { | ||
| return None; | ||
| } | ||
| } | ||
|
|
||
| CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { | ||
| switch (CC) { | ||
| default: | ||
| return CCCR_Warning; | ||
| case CC_C: | ||
| case CC_OpenCLKernel: | ||
| return CCCR_OK; | ||
| } | ||
| } | ||
|
|
||
| // In amdgcn target the null pointer in global, constant, and generic | ||
| // address space has value 0 but in private and local address space has | ||
| // value ~0. | ||
| uint64_t getNullPointerValue(unsigned AS) const override { | ||
| return AS == LangAS::opencl_local ? ~0 : 0; | ||
| } | ||
| }; | ||
|
|
||
| } // namespace targets | ||
| } // namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_LIB_BASIC_TARGETS_AMDGPU_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,320 @@ | ||
| //===--- AVR.cpp - Implement AVR target feature support -------------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file implements AVR TargetInfo objects. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "AVR.h" | ||
| #include "clang/Basic/MacroBuilder.h" | ||
| #include "llvm/ADT/StringSwitch.h" | ||
|
|
||
| using namespace clang; | ||
| using namespace clang::targets; | ||
|
|
||
| namespace clang { | ||
| namespace targets { | ||
|
|
||
| /// Information about a specific microcontroller. | ||
| struct LLVM_LIBRARY_VISIBILITY MCUInfo { | ||
| const char *Name; | ||
| const char *DefineName; | ||
| }; | ||
|
|
||
| // This list should be kept up-to-date with AVRDevices.td in LLVM. | ||
| static ArrayRef<MCUInfo> AVRMcus = { | ||
| {"at90s1200", "__AVR_AT90S1200__"}, | ||
| {"attiny11", "__AVR_ATtiny11__"}, | ||
| {"attiny12", "__AVR_ATtiny12__"}, | ||
| {"attiny15", "__AVR_ATtiny15__"}, | ||
| {"attiny28", "__AVR_ATtiny28__"}, | ||
| {"at90s2313", "__AVR_AT90S2313__"}, | ||
| {"at90s2323", "__AVR_AT90S2323__"}, | ||
| {"at90s2333", "__AVR_AT90S2333__"}, | ||
| {"at90s2343", "__AVR_AT90S2343__"}, | ||
| {"attiny22", "__AVR_ATtiny22__"}, | ||
| {"attiny26", "__AVR_ATtiny26__"}, | ||
| {"at86rf401", "__AVR_AT86RF401__"}, | ||
| {"at90s4414", "__AVR_AT90S4414__"}, | ||
| {"at90s4433", "__AVR_AT90S4433__"}, | ||
| {"at90s4434", "__AVR_AT90S4434__"}, | ||
| {"at90s8515", "__AVR_AT90S8515__"}, | ||
| {"at90c8534", "__AVR_AT90c8534__"}, | ||
| {"at90s8535", "__AVR_AT90S8535__"}, | ||
| {"ata5272", "__AVR_ATA5272__"}, | ||
| {"attiny13", "__AVR_ATtiny13__"}, | ||
| {"attiny13a", "__AVR_ATtiny13A__"}, | ||
| {"attiny2313", "__AVR_ATtiny2313__"}, | ||
| {"attiny2313a", "__AVR_ATtiny2313A__"}, | ||
| {"attiny24", "__AVR_ATtiny24__"}, | ||
| {"attiny24a", "__AVR_ATtiny24A__"}, | ||
| {"attiny4313", "__AVR_ATtiny4313__"}, | ||
| {"attiny44", "__AVR_ATtiny44__"}, | ||
| {"attiny44a", "__AVR_ATtiny44A__"}, | ||
| {"attiny84", "__AVR_ATtiny84__"}, | ||
| {"attiny84a", "__AVR_ATtiny84A__"}, | ||
| {"attiny25", "__AVR_ATtiny25__"}, | ||
| {"attiny45", "__AVR_ATtiny45__"}, | ||
| {"attiny85", "__AVR_ATtiny85__"}, | ||
| {"attiny261", "__AVR_ATtiny261__"}, | ||
| {"attiny261a", "__AVR_ATtiny261A__"}, | ||
| {"attiny461", "__AVR_ATtiny461__"}, | ||
| {"attiny461a", "__AVR_ATtiny461A__"}, | ||
| {"attiny861", "__AVR_ATtiny861__"}, | ||
| {"attiny861a", "__AVR_ATtiny861A__"}, | ||
| {"attiny87", "__AVR_ATtiny87__"}, | ||
| {"attiny43u", "__AVR_ATtiny43U__"}, | ||
| {"attiny48", "__AVR_ATtiny48__"}, | ||
| {"attiny88", "__AVR_ATtiny88__"}, | ||
| {"attiny828", "__AVR_ATtiny828__"}, | ||
| {"at43usb355", "__AVR_AT43USB355__"}, | ||
| {"at76c711", "__AVR_AT76C711__"}, | ||
| {"atmega103", "__AVR_ATmega103__"}, | ||
| {"at43usb320", "__AVR_AT43USB320__"}, | ||
| {"attiny167", "__AVR_ATtiny167__"}, | ||
| {"at90usb82", "__AVR_AT90USB82__"}, | ||
| {"at90usb162", "__AVR_AT90USB162__"}, | ||
| {"ata5505", "__AVR_ATA5505__"}, | ||
| {"atmega8u2", "__AVR_ATmega8U2__"}, | ||
| {"atmega16u2", "__AVR_ATmega16U2__"}, | ||
| {"atmega32u2", "__AVR_ATmega32U2__"}, | ||
| {"attiny1634", "__AVR_ATtiny1634__"}, | ||
| {"atmega8", "__AVR_ATmega8__"}, | ||
| {"ata6289", "__AVR_ATA6289__"}, | ||
| {"atmega8a", "__AVR_ATmega8A__"}, | ||
| {"ata6285", "__AVR_ATA6285__"}, | ||
| {"ata6286", "__AVR_ATA6286__"}, | ||
| {"atmega48", "__AVR_ATmega48__"}, | ||
| {"atmega48a", "__AVR_ATmega48A__"}, | ||
| {"atmega48pa", "__AVR_ATmega48PA__"}, | ||
| {"atmega48p", "__AVR_ATmega48P__"}, | ||
| {"atmega88", "__AVR_ATmega88__"}, | ||
| {"atmega88a", "__AVR_ATmega88A__"}, | ||
| {"atmega88p", "__AVR_ATmega88P__"}, | ||
| {"atmega88pa", "__AVR_ATmega88PA__"}, | ||
| {"atmega8515", "__AVR_ATmega8515__"}, | ||
| {"atmega8535", "__AVR_ATmega8535__"}, | ||
| {"atmega8hva", "__AVR_ATmega8HVA__"}, | ||
| {"at90pwm1", "__AVR_AT90PWM1__"}, | ||
| {"at90pwm2", "__AVR_AT90PWM2__"}, | ||
| {"at90pwm2b", "__AVR_AT90PWM2B__"}, | ||
| {"at90pwm3", "__AVR_AT90PWM3__"}, | ||
| {"at90pwm3b", "__AVR_AT90PWM3B__"}, | ||
| {"at90pwm81", "__AVR_AT90PWM81__"}, | ||
| {"ata5790", "__AVR_ATA5790__"}, | ||
| {"ata5795", "__AVR_ATA5795__"}, | ||
| {"atmega16", "__AVR_ATmega16__"}, | ||
| {"atmega16a", "__AVR_ATmega16A__"}, | ||
| {"atmega161", "__AVR_ATmega161__"}, | ||
| {"atmega162", "__AVR_ATmega162__"}, | ||
| {"atmega163", "__AVR_ATmega163__"}, | ||
| {"atmega164a", "__AVR_ATmega164A__"}, | ||
| {"atmega164p", "__AVR_ATmega164P__"}, | ||
| {"atmega164pa", "__AVR_ATmega164PA__"}, | ||
| {"atmega165", "__AVR_ATmega165__"}, | ||
| {"atmega165a", "__AVR_ATmega165A__"}, | ||
| {"atmega165p", "__AVR_ATmega165P__"}, | ||
| {"atmega165pa", "__AVR_ATmega165PA__"}, | ||
| {"atmega168", "__AVR_ATmega168__"}, | ||
| {"atmega168a", "__AVR_ATmega168A__"}, | ||
| {"atmega168p", "__AVR_ATmega168P__"}, | ||
| {"atmega168pa", "__AVR_ATmega168PA__"}, | ||
| {"atmega169", "__AVR_ATmega169__"}, | ||
| {"atmega169a", "__AVR_ATmega169A__"}, | ||
| {"atmega169p", "__AVR_ATmega169P__"}, | ||
| {"atmega169pa", "__AVR_ATmega169PA__"}, | ||
| {"atmega32", "__AVR_ATmega32__"}, | ||
| {"atmega32a", "__AVR_ATmega32A__"}, | ||
| {"atmega323", "__AVR_ATmega323__"}, | ||
| {"atmega324a", "__AVR_ATmega324A__"}, | ||
| {"atmega324p", "__AVR_ATmega324P__"}, | ||
| {"atmega324pa", "__AVR_ATmega324PA__"}, | ||
| {"atmega325", "__AVR_ATmega325__"}, | ||
| {"atmega325a", "__AVR_ATmega325A__"}, | ||
| {"atmega325p", "__AVR_ATmega325P__"}, | ||
| {"atmega325pa", "__AVR_ATmega325PA__"}, | ||
| {"atmega3250", "__AVR_ATmega3250__"}, | ||
| {"atmega3250a", "__AVR_ATmega3250A__"}, | ||
| {"atmega3250p", "__AVR_ATmega3250P__"}, | ||
| {"atmega3250pa", "__AVR_ATmega3250PA__"}, | ||
| {"atmega328", "__AVR_ATmega328__"}, | ||
| {"atmega328p", "__AVR_ATmega328P__"}, | ||
| {"atmega329", "__AVR_ATmega329__"}, | ||
| {"atmega329a", "__AVR_ATmega329A__"}, | ||
| {"atmega329p", "__AVR_ATmega329P__"}, | ||
| {"atmega329pa", "__AVR_ATmega329PA__"}, | ||
| {"atmega3290", "__AVR_ATmega3290__"}, | ||
| {"atmega3290a", "__AVR_ATmega3290A__"}, | ||
| {"atmega3290p", "__AVR_ATmega3290P__"}, | ||
| {"atmega3290pa", "__AVR_ATmega3290PA__"}, | ||
| {"atmega406", "__AVR_ATmega406__"}, | ||
| {"atmega64", "__AVR_ATmega64__"}, | ||
| {"atmega64a", "__AVR_ATmega64A__"}, | ||
| {"atmega640", "__AVR_ATmega640__"}, | ||
| {"atmega644", "__AVR_ATmega644__"}, | ||
| {"atmega644a", "__AVR_ATmega644A__"}, | ||
| {"atmega644p", "__AVR_ATmega644P__"}, | ||
| {"atmega644pa", "__AVR_ATmega644PA__"}, | ||
| {"atmega645", "__AVR_ATmega645__"}, | ||
| {"atmega645a", "__AVR_ATmega645A__"}, | ||
| {"atmega645p", "__AVR_ATmega645P__"}, | ||
| {"atmega649", "__AVR_ATmega649__"}, | ||
| {"atmega649a", "__AVR_ATmega649A__"}, | ||
| {"atmega649p", "__AVR_ATmega649P__"}, | ||
| {"atmega6450", "__AVR_ATmega6450__"}, | ||
| {"atmega6450a", "__AVR_ATmega6450A__"}, | ||
| {"atmega6450p", "__AVR_ATmega6450P__"}, | ||
| {"atmega6490", "__AVR_ATmega6490__"}, | ||
| {"atmega6490a", "__AVR_ATmega6490A__"}, | ||
| {"atmega6490p", "__AVR_ATmega6490P__"}, | ||
| {"atmega64rfr2", "__AVR_ATmega64RFR2__"}, | ||
| {"atmega644rfr2", "__AVR_ATmega644RFR2__"}, | ||
| {"atmega16hva", "__AVR_ATmega16HVA__"}, | ||
| {"atmega16hva2", "__AVR_ATmega16HVA2__"}, | ||
| {"atmega16hvb", "__AVR_ATmega16HVB__"}, | ||
| {"atmega16hvbrevb", "__AVR_ATmega16HVBREVB__"}, | ||
| {"atmega32hvb", "__AVR_ATmega32HVB__"}, | ||
| {"atmega32hvbrevb", "__AVR_ATmega32HVBREVB__"}, | ||
| {"atmega64hve", "__AVR_ATmega64HVE__"}, | ||
| {"at90can32", "__AVR_AT90CAN32__"}, | ||
| {"at90can64", "__AVR_AT90CAN64__"}, | ||
| {"at90pwm161", "__AVR_AT90PWM161__"}, | ||
| {"at90pwm216", "__AVR_AT90PWM216__"}, | ||
| {"at90pwm316", "__AVR_AT90PWM316__"}, | ||
| {"atmega32c1", "__AVR_ATmega32C1__"}, | ||
| {"atmega64c1", "__AVR_ATmega64C1__"}, | ||
| {"atmega16m1", "__AVR_ATmega16M1__"}, | ||
| {"atmega32m1", "__AVR_ATmega32M1__"}, | ||
| {"atmega64m1", "__AVR_ATmega64M1__"}, | ||
| {"atmega16u4", "__AVR_ATmega16U4__"}, | ||
| {"atmega32u4", "__AVR_ATmega32U4__"}, | ||
| {"atmega32u6", "__AVR_ATmega32U6__"}, | ||
| {"at90usb646", "__AVR_AT90USB646__"}, | ||
| {"at90usb647", "__AVR_AT90USB647__"}, | ||
| {"at90scr100", "__AVR_AT90SCR100__"}, | ||
| {"at94k", "__AVR_AT94K__"}, | ||
| {"m3000", "__AVR_AT000__"}, | ||
| {"atmega128", "__AVR_ATmega128__"}, | ||
| {"atmega128a", "__AVR_ATmega128A__"}, | ||
| {"atmega1280", "__AVR_ATmega1280__"}, | ||
| {"atmega1281", "__AVR_ATmega1281__"}, | ||
| {"atmega1284", "__AVR_ATmega1284__"}, | ||
| {"atmega1284p", "__AVR_ATmega1284P__"}, | ||
| {"atmega128rfa1", "__AVR_ATmega128RFA1__"}, | ||
| {"atmega128rfr2", "__AVR_ATmega128RFR2__"}, | ||
| {"atmega1284rfr2", "__AVR_ATmega1284RFR2__"}, | ||
| {"at90can128", "__AVR_AT90CAN128__"}, | ||
| {"at90usb1286", "__AVR_AT90USB1286__"}, | ||
| {"at90usb1287", "__AVR_AT90USB1287__"}, | ||
| {"atmega2560", "__AVR_ATmega2560__"}, | ||
| {"atmega2561", "__AVR_ATmega2561__"}, | ||
| {"atmega256rfr2", "__AVR_ATmega256RFR2__"}, | ||
| {"atmega2564rfr2", "__AVR_ATmega2564RFR2__"}, | ||
| {"atxmega16a4", "__AVR_ATxmega16A4__"}, | ||
| {"atxmega16a4u", "__AVR_ATxmega16a4U__"}, | ||
| {"atxmega16c4", "__AVR_ATxmega16C4__"}, | ||
| {"atxmega16d4", "__AVR_ATxmega16D4__"}, | ||
| {"atxmega32a4", "__AVR_ATxmega32A4__"}, | ||
| {"atxmega32a4u", "__AVR_ATxmega32A4U__"}, | ||
| {"atxmega32c4", "__AVR_ATxmega32C4__"}, | ||
| {"atxmega32d4", "__AVR_ATxmega32D4__"}, | ||
| {"atxmega32e5", "__AVR_ATxmega32E5__"}, | ||
| {"atxmega16e5", "__AVR_ATxmega16E5__"}, | ||
| {"atxmega8e5", "__AVR_ATxmega8E5__"}, | ||
| {"atxmega32x1", "__AVR_ATxmega32X1__"}, | ||
| {"atxmega64a3", "__AVR_ATxmega64A3__"}, | ||
| {"atxmega64a3u", "__AVR_ATxmega64A3U__"}, | ||
| {"atxmega64a4u", "__AVR_ATxmega64A4U__"}, | ||
| {"atxmega64b1", "__AVR_ATxmega64B1__"}, | ||
| {"atxmega64b3", "__AVR_ATxmega64B3__"}, | ||
| {"atxmega64c3", "__AVR_ATxmega64C3__"}, | ||
| {"atxmega64d3", "__AVR_ATxmega64D3__"}, | ||
| {"atxmega64d4", "__AVR_ATxmega64D4__"}, | ||
| {"atxmega64a1", "__AVR_ATxmega64A1__"}, | ||
| {"atxmega64a1u", "__AVR_ATxmega64A1U__"}, | ||
| {"atxmega128a3", "__AVR_ATxmega128A3__"}, | ||
| {"atxmega128a3u", "__AVR_ATxmega128A3U__"}, | ||
| {"atxmega128b1", "__AVR_ATxmega128B1__"}, | ||
| {"atxmega128b3", "__AVR_ATxmega128B3__"}, | ||
| {"atxmega128c3", "__AVR_ATxmega128C3__"}, | ||
| {"atxmega128d3", "__AVR_ATxmega128D3__"}, | ||
| {"atxmega128d4", "__AVR_ATxmega128D4__"}, | ||
| {"atxmega192a3", "__AVR_ATxmega192A3__"}, | ||
| {"atxmega192a3u", "__AVR_ATxmega192A3U__"}, | ||
| {"atxmega192c3", "__AVR_ATxmega192C3__"}, | ||
| {"atxmega192d3", "__AVR_ATxmega192D3__"}, | ||
| {"atxmega256a3", "__AVR_ATxmega256A3__"}, | ||
| {"atxmega256a3u", "__AVR_ATxmega256A3U__"}, | ||
| {"atxmega256a3b", "__AVR_ATxmega256A3B__"}, | ||
| {"atxmega256a3bu", "__AVR_ATxmega256A3BU__"}, | ||
| {"atxmega256c3", "__AVR_ATxmega256C3__"}, | ||
| {"atxmega256d3", "__AVR_ATxmega256D3__"}, | ||
| {"atxmega384c3", "__AVR_ATxmega384C3__"}, | ||
| {"atxmega384d3", "__AVR_ATxmega384D3__"}, | ||
| {"atxmega128a1", "__AVR_ATxmega128A1__"}, | ||
| {"atxmega128a1u", "__AVR_ATxmega128A1U__"}, | ||
| {"atxmega128a4u", "__AVR_ATxmega128a4U__"}, | ||
| {"attiny4", "__AVR_ATtiny4__"}, | ||
| {"attiny5", "__AVR_ATtiny5__"}, | ||
| {"attiny9", "__AVR_ATtiny9__"}, | ||
| {"attiny10", "__AVR_ATtiny10__"}, | ||
| {"attiny20", "__AVR_ATtiny20__"}, | ||
| {"attiny40", "__AVR_ATtiny40__"}, | ||
| {"attiny102", "__AVR_ATtiny102__"}, | ||
| {"attiny104", "__AVR_ATtiny104__"}, | ||
| }; | ||
|
|
||
| } // namespace targets | ||
| } // namespace clang | ||
|
|
||
| bool AVRTargetInfo::isValidCPUName(StringRef Name) const { | ||
| bool IsFamily = llvm::StringSwitch<bool>(Name) | ||
| .Case("avr1", true) | ||
| .Case("avr2", true) | ||
| .Case("avr25", true) | ||
| .Case("avr3", true) | ||
| .Case("avr31", true) | ||
| .Case("avr35", true) | ||
| .Case("avr4", true) | ||
| .Case("avr5", true) | ||
| .Case("avr51", true) | ||
| .Case("avr6", true) | ||
| .Case("avrxmega1", true) | ||
| .Case("avrxmega2", true) | ||
| .Case("avrxmega3", true) | ||
| .Case("avrxmega4", true) | ||
| .Case("avrxmega5", true) | ||
| .Case("avrxmega6", true) | ||
| .Case("avrxmega7", true) | ||
| .Case("avrtiny", true) | ||
| .Default(false); | ||
|
|
||
| bool IsMCU = | ||
| std::find_if(AVRMcus.begin(), AVRMcus.end(), [&](const MCUInfo &Info) { | ||
| return Info.Name == Name; | ||
| }) != AVRMcus.end(); | ||
| return IsFamily || IsMCU; | ||
| } | ||
|
|
||
| void AVRTargetInfo::getTargetDefines(const LangOptions &Opts, | ||
| MacroBuilder &Builder) const { | ||
| Builder.defineMacro("AVR"); | ||
| Builder.defineMacro("__AVR"); | ||
| Builder.defineMacro("__AVR__"); | ||
|
|
||
| if (!this->CPU.empty()) { | ||
| auto It = | ||
| std::find_if(AVRMcus.begin(), AVRMcus.end(), [&](const MCUInfo &Info) { | ||
| return Info.Name == this->CPU; | ||
| }); | ||
|
|
||
| if (It != AVRMcus.end()) | ||
| Builder.defineMacro(It->DefineName); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,186 @@ | ||
| //===--- AVR.h - Declare AVR target feature support -------------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file declares AVR TargetInfo objects. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_AVR_H | ||
| #define LLVM_CLANG_LIB_BASIC_TARGETS_AVR_H | ||
|
|
||
| #include "clang/Basic/TargetInfo.h" | ||
| #include "clang/Basic/TargetOptions.h" | ||
| #include "llvm/ADT/Triple.h" | ||
| #include "llvm/Support/Compiler.h" | ||
|
|
||
| namespace clang { | ||
| namespace targets { | ||
|
|
||
| // AVR Target | ||
| class LLVM_LIBRARY_VISIBILITY AVRTargetInfo : public TargetInfo { | ||
| public: | ||
| AVRTargetInfo(const llvm::Triple &Triple, const TargetOptions &) | ||
| : TargetInfo(Triple) { | ||
| TLSSupported = false; | ||
| PointerWidth = 16; | ||
| PointerAlign = 8; | ||
| IntWidth = 16; | ||
| IntAlign = 8; | ||
| LongWidth = 32; | ||
| LongAlign = 8; | ||
| LongLongWidth = 64; | ||
| LongLongAlign = 8; | ||
| SuitableAlign = 8; | ||
| DefaultAlignForAttributeAligned = 8; | ||
| HalfWidth = 16; | ||
| HalfAlign = 8; | ||
| FloatWidth = 32; | ||
| FloatAlign = 8; | ||
| DoubleWidth = 32; | ||
| DoubleAlign = 8; | ||
| DoubleFormat = &llvm::APFloat::IEEEsingle(); | ||
| LongDoubleWidth = 32; | ||
| LongDoubleAlign = 8; | ||
| LongDoubleFormat = &llvm::APFloat::IEEEsingle(); | ||
| SizeType = UnsignedInt; | ||
| PtrDiffType = SignedInt; | ||
| IntPtrType = SignedInt; | ||
| Char16Type = UnsignedInt; | ||
| WCharType = SignedInt; | ||
| WIntType = SignedInt; | ||
| Char32Type = UnsignedLong; | ||
| SigAtomicType = SignedChar; | ||
| resetDataLayout("e-p:16:16:16-i8:8:8-i16:16:16-i32:32:32-i64:64:64" | ||
| "-f32:32:32-f64:64:64-n8"); | ||
| } | ||
|
|
||
| void getTargetDefines(const LangOptions &Opts, | ||
| MacroBuilder &Builder) const override; | ||
|
|
||
| ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; } | ||
|
|
||
| BuiltinVaListKind getBuiltinVaListKind() const override { | ||
| return TargetInfo::VoidPtrBuiltinVaList; | ||
| } | ||
|
|
||
| const char *getClobbers() const override { return ""; } | ||
|
|
||
| ArrayRef<const char *> getGCCRegNames() const override { | ||
| static const char *const GCCRegNames[] = { | ||
| "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", | ||
| "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", | ||
| "r20", "r21", "r22", "r23", "r24", "r25", "X", "Y", "Z", "SP" | ||
| }; | ||
| return llvm::makeArrayRef(GCCRegNames); | ||
| } | ||
|
|
||
| ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { | ||
| return None; | ||
| } | ||
|
|
||
| ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override { | ||
| static const TargetInfo::AddlRegName AddlRegNames[] = { | ||
| {{"r26", "r27"}, 26}, | ||
| {{"r28", "r29"}, 27}, | ||
| {{"r30", "r31"}, 28}, | ||
| {{"SPL", "SPH"}, 29}, | ||
| }; | ||
| return llvm::makeArrayRef(AddlRegNames); | ||
| } | ||
|
|
||
| bool validateAsmConstraint(const char *&Name, | ||
| TargetInfo::ConstraintInfo &Info) const override { | ||
| // There aren't any multi-character AVR specific constraints. | ||
| if (StringRef(Name).size() > 1) | ||
| return false; | ||
|
|
||
| switch (*Name) { | ||
| default: | ||
| return false; | ||
| case 'a': // Simple upper registers | ||
| case 'b': // Base pointer registers pairs | ||
| case 'd': // Upper register | ||
| case 'l': // Lower registers | ||
| case 'e': // Pointer register pairs | ||
| case 'q': // Stack pointer register | ||
| case 'r': // Any register | ||
| case 'w': // Special upper register pairs | ||
| case 't': // Temporary register | ||
| case 'x': | ||
| case 'X': // Pointer register pair X | ||
| case 'y': | ||
| case 'Y': // Pointer register pair Y | ||
| case 'z': | ||
| case 'Z': // Pointer register pair Z | ||
| Info.setAllowsRegister(); | ||
| return true; | ||
| case 'I': // 6-bit positive integer constant | ||
| Info.setRequiresImmediate(0, 63); | ||
| return true; | ||
| case 'J': // 6-bit negative integer constant | ||
| Info.setRequiresImmediate(-63, 0); | ||
| return true; | ||
| case 'K': // Integer constant (Range: 2) | ||
| Info.setRequiresImmediate(2); | ||
| return true; | ||
| case 'L': // Integer constant (Range: 0) | ||
| Info.setRequiresImmediate(0); | ||
| return true; | ||
| case 'M': // 8-bit integer constant | ||
| Info.setRequiresImmediate(0, 0xff); | ||
| return true; | ||
| case 'N': // Integer constant (Range: -1) | ||
| Info.setRequiresImmediate(-1); | ||
| return true; | ||
| case 'O': // Integer constant (Range: 8, 16, 24) | ||
| Info.setRequiresImmediate({8, 16, 24}); | ||
| return true; | ||
| case 'P': // Integer constant (Range: 1) | ||
| Info.setRequiresImmediate(1); | ||
| return true; | ||
| case 'R': // Integer constant (Range: -6 to 5) | ||
| Info.setRequiresImmediate(-6, 5); | ||
| return true; | ||
| case 'G': // Floating point constant | ||
| case 'Q': // A memory address based on Y or Z pointer with displacement. | ||
| return true; | ||
| } | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final { | ||
| // AVR prefers int for 16-bit integers. | ||
| return BitWidth == 16 ? (IsSigned ? SignedInt : UnsignedInt) | ||
| : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned); | ||
| } | ||
|
|
||
| IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final { | ||
| // AVR uses int for int_least16_t and int_fast16_t. | ||
| return BitWidth == 16 | ||
| ? (IsSigned ? SignedInt : UnsignedInt) | ||
| : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned); | ||
| } | ||
|
|
||
| bool isValidCPUName(StringRef Name) const override; | ||
| bool setCPU(const std::string &Name) override { | ||
| bool isValid = isValidCPUName(Name); | ||
| if (isValid) | ||
| CPU = Name; | ||
| return isValid; | ||
| } | ||
|
|
||
| protected: | ||
| std::string CPU; | ||
| }; | ||
|
|
||
| } // namespace targets | ||
| } // namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_LIB_BASIC_TARGETS_AVR_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| //===--- BPF.cpp - Implement BPF target feature support -------------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file implements BPF TargetInfo objects. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "BPF.h" | ||
| #include "Targets.h" | ||
| #include "clang/Basic/MacroBuilder.h" | ||
|
|
||
| using namespace clang; | ||
| using namespace clang::targets; | ||
|
|
||
| void BPFTargetInfo::getTargetDefines(const LangOptions &Opts, | ||
| MacroBuilder &Builder) const { | ||
| DefineStd(Builder, "bpf", Opts); | ||
| Builder.defineMacro("__BPF__"); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| //===--- BPF.h - Declare BPF target feature support -------------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file declares BPF TargetInfo objects. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_BPF_H | ||
| #define LLVM_CLANG_LIB_BASIC_TARGETS_BPF_H | ||
|
|
||
| #include "clang/Basic/TargetInfo.h" | ||
| #include "clang/Basic/TargetOptions.h" | ||
| #include "llvm/ADT/Triple.h" | ||
| #include "llvm/Support/Compiler.h" | ||
|
|
||
| namespace clang { | ||
| namespace targets { | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public TargetInfo { | ||
| public: | ||
| BPFTargetInfo(const llvm::Triple &Triple, const TargetOptions &) | ||
| : TargetInfo(Triple) { | ||
| LongWidth = LongAlign = PointerWidth = PointerAlign = 64; | ||
| SizeType = UnsignedLong; | ||
| PtrDiffType = SignedLong; | ||
| IntPtrType = SignedLong; | ||
| IntMaxType = SignedLong; | ||
| Int64Type = SignedLong; | ||
| RegParmMax = 5; | ||
| if (Triple.getArch() == llvm::Triple::bpfeb) { | ||
| resetDataLayout("E-m:e-p:64:64-i64:64-n32:64-S128"); | ||
| } else { | ||
| resetDataLayout("e-m:e-p:64:64-i64:64-n32:64-S128"); | ||
| } | ||
| MaxAtomicPromoteWidth = 64; | ||
| MaxAtomicInlineWidth = 64; | ||
| TLSSupported = false; | ||
| } | ||
|
|
||
| void getTargetDefines(const LangOptions &Opts, | ||
| MacroBuilder &Builder) const override; | ||
|
|
||
| bool hasFeature(StringRef Feature) const override { return Feature == "bpf"; } | ||
|
|
||
| ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; } | ||
|
|
||
| const char *getClobbers() const override { return ""; } | ||
|
|
||
| BuiltinVaListKind getBuiltinVaListKind() const override { | ||
| return TargetInfo::VoidPtrBuiltinVaList; | ||
| } | ||
|
|
||
| ArrayRef<const char *> getGCCRegNames() const override { return None; } | ||
|
|
||
| bool validateAsmConstraint(const char *&Name, | ||
| TargetInfo::ConstraintInfo &info) const override { | ||
| return true; | ||
| } | ||
|
|
||
| ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { | ||
| return None; | ||
| } | ||
|
|
||
| CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { | ||
| switch (CC) { | ||
| default: | ||
| return CCCR_Warning; | ||
| case CC_C: | ||
| case CC_OpenCLKernel: | ||
| return CCCR_OK; | ||
| } | ||
| } | ||
| }; | ||
| } // namespace targets | ||
| } // namespace clang | ||
| #endif // LLVM_CLANG_LIB_BASIC_TARGETS_BPF_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,159 @@ | ||
| //===--- Hexagon.cpp - Implement Hexagon target feature support -----------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file implements Hexagon TargetInfo objects. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "Hexagon.h" | ||
| #include "Targets.h" | ||
| #include "clang/Basic/MacroBuilder.h" | ||
| #include "clang/Basic/TargetBuiltins.h" | ||
| #include "llvm/ADT/StringSwitch.h" | ||
|
|
||
| using namespace clang; | ||
| using namespace clang::targets; | ||
|
|
||
| void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts, | ||
| MacroBuilder &Builder) const { | ||
| Builder.defineMacro("__qdsp6__", "1"); | ||
| Builder.defineMacro("__hexagon__", "1"); | ||
|
|
||
| if (CPU == "hexagonv4") { | ||
| Builder.defineMacro("__HEXAGON_V4__"); | ||
| Builder.defineMacro("__HEXAGON_ARCH__", "4"); | ||
| if (Opts.HexagonQdsp6Compat) { | ||
| Builder.defineMacro("__QDSP6_V4__"); | ||
| Builder.defineMacro("__QDSP6_ARCH__", "4"); | ||
| } | ||
| } else if (CPU == "hexagonv5") { | ||
| Builder.defineMacro("__HEXAGON_V5__"); | ||
| Builder.defineMacro("__HEXAGON_ARCH__", "5"); | ||
| if (Opts.HexagonQdsp6Compat) { | ||
| Builder.defineMacro("__QDSP6_V5__"); | ||
| Builder.defineMacro("__QDSP6_ARCH__", "5"); | ||
| } | ||
| } else if (CPU == "hexagonv55") { | ||
| Builder.defineMacro("__HEXAGON_V55__"); | ||
| Builder.defineMacro("__HEXAGON_ARCH__", "55"); | ||
| Builder.defineMacro("__QDSP6_V55__"); | ||
| Builder.defineMacro("__QDSP6_ARCH__", "55"); | ||
| } else if (CPU == "hexagonv60") { | ||
| Builder.defineMacro("__HEXAGON_V60__"); | ||
| Builder.defineMacro("__HEXAGON_ARCH__", "60"); | ||
| Builder.defineMacro("__QDSP6_V60__"); | ||
| Builder.defineMacro("__QDSP6_ARCH__", "60"); | ||
| } else if (CPU == "hexagonv62") { | ||
| Builder.defineMacro("__HEXAGON_V62__"); | ||
| Builder.defineMacro("__HEXAGON_ARCH__", "62"); | ||
| } | ||
|
|
||
| if (hasFeature("hvx")) { | ||
| Builder.defineMacro("__HVX__"); | ||
| if (hasFeature("hvx-double")) | ||
| Builder.defineMacro("__HVXDBL__"); | ||
| } | ||
| } | ||
|
|
||
| bool HexagonTargetInfo::initFeatureMap( | ||
| llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, | ||
| const std::vector<std::string> &FeaturesVec) const { | ||
| // Default for v60: -hvx, -hvx-double. | ||
| Features["hvx"] = false; | ||
| Features["hvx-double"] = false; | ||
| Features["long-calls"] = false; | ||
|
|
||
| return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); | ||
| } | ||
|
|
||
| bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, | ||
| DiagnosticsEngine &Diags) { | ||
| for (auto &F : Features) { | ||
| if (F == "+hvx") | ||
| HasHVX = true; | ||
| else if (F == "-hvx") | ||
| HasHVX = HasHVXDouble = false; | ||
| else if (F == "+hvx-double") | ||
| HasHVX = HasHVXDouble = true; | ||
| else if (F == "-hvx-double") | ||
| HasHVXDouble = false; | ||
|
|
||
| if (F == "+long-calls") | ||
| UseLongCalls = true; | ||
| else if (F == "-long-calls") | ||
| UseLongCalls = false; | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| void HexagonTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, | ||
| StringRef Name, bool Enabled) const { | ||
| if (Enabled) { | ||
| if (Name == "hvx-double") | ||
| Features["hvx"] = true; | ||
| } else { | ||
| if (Name == "hvx") | ||
| Features["hvx-double"] = false; | ||
| } | ||
| Features[Name] = Enabled; | ||
| } | ||
|
|
||
| const char *const HexagonTargetInfo::GCCRegNames[] = { | ||
| "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", | ||
| "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", | ||
| "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", | ||
| "r27", "r28", "r29", "r30", "r31", "p0", "p1", "p2", "p3", | ||
| "sa0", "lc0", "sa1", "lc1", "m0", "m1", "usr", "ugp" | ||
| }; | ||
|
|
||
| ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const { | ||
| return llvm::makeArrayRef(GCCRegNames); | ||
| } | ||
|
|
||
| const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = { | ||
| {{"sp"}, "r29"}, | ||
| {{"fp"}, "r30"}, | ||
| {{"lr"}, "r31"}, | ||
| }; | ||
|
|
||
| ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const { | ||
| return llvm::makeArrayRef(GCCRegAliases); | ||
| } | ||
|
|
||
| const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = { | ||
| #define BUILTIN(ID, TYPE, ATTRS) \ | ||
| {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, | ||
| #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ | ||
| {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, | ||
| #include "clang/Basic/BuiltinsHexagon.def" | ||
| }; | ||
|
|
||
| bool HexagonTargetInfo::hasFeature(StringRef Feature) const { | ||
| return llvm::StringSwitch<bool>(Feature) | ||
| .Case("hexagon", true) | ||
| .Case("hvx", HasHVX) | ||
| .Case("hvx-double", HasHVXDouble) | ||
| .Case("long-calls", UseLongCalls) | ||
| .Default(false); | ||
| } | ||
|
|
||
| const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) { | ||
| return llvm::StringSwitch<const char *>(Name) | ||
| .Case("hexagonv4", "4") | ||
| .Case("hexagonv5", "5") | ||
| .Case("hexagonv55", "55") | ||
| .Case("hexagonv60", "60") | ||
| .Case("hexagonv62", "62") | ||
| .Default(nullptr); | ||
| } | ||
|
|
||
| ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const { | ||
| return llvm::makeArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin - | ||
| Builtin::FirstTSBuiltin); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,130 @@ | ||
| //===--- Hexagon.h - Declare Hexagon target feature support -----*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file declares Hexagon TargetInfo objects. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_HEXAGON_H | ||
| #define LLVM_CLANG_LIB_BASIC_TARGETS_HEXAGON_H | ||
|
|
||
| #include "clang/Basic/TargetInfo.h" | ||
| #include "clang/Basic/TargetOptions.h" | ||
| #include "llvm/ADT/Triple.h" | ||
| #include "llvm/Support/Compiler.h" | ||
|
|
||
| namespace clang { | ||
| namespace targets { | ||
|
|
||
| // Hexagon abstract base class | ||
| class LLVM_LIBRARY_VISIBILITY HexagonTargetInfo : public TargetInfo { | ||
|
|
||
| static const Builtin::Info BuiltinInfo[]; | ||
| static const char *const GCCRegNames[]; | ||
| static const TargetInfo::GCCRegAlias GCCRegAliases[]; | ||
| std::string CPU; | ||
| bool HasHVX, HasHVXDouble; | ||
| bool UseLongCalls; | ||
|
|
||
| public: | ||
| HexagonTargetInfo(const llvm::Triple &Triple, const TargetOptions &) | ||
| : TargetInfo(Triple) { | ||
| // Specify the vector alignment explicitly. For v512x1, the calculated | ||
| // alignment would be 512*alignment(i1), which is 512 bytes, instead of | ||
| // the required minimum of 64 bytes. | ||
| resetDataLayout( | ||
| "e-m:e-p:32:32:32-a:0-n16:32-" | ||
| "i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-" | ||
| "v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"); | ||
| SizeType = UnsignedInt; | ||
| PtrDiffType = SignedInt; | ||
| IntPtrType = SignedInt; | ||
|
|
||
| // {} in inline assembly are packet specifiers, not assembly variant | ||
| // specifiers. | ||
| NoAsmVariants = true; | ||
|
|
||
| LargeArrayMinWidth = 64; | ||
| LargeArrayAlign = 64; | ||
| UseBitFieldTypeAlignment = true; | ||
| ZeroLengthBitfieldBoundary = 32; | ||
| HasHVX = HasHVXDouble = false; | ||
| UseLongCalls = false; | ||
| } | ||
|
|
||
| ArrayRef<Builtin::Info> getTargetBuiltins() const override; | ||
|
|
||
| bool validateAsmConstraint(const char *&Name, | ||
| TargetInfo::ConstraintInfo &Info) const override { | ||
| switch (*Name) { | ||
| case 'v': | ||
| case 'q': | ||
| if (HasHVX) { | ||
| Info.setAllowsRegister(); | ||
| return true; | ||
| } | ||
| break; | ||
| case 'a': // Modifier register m0-m1. | ||
| Info.setAllowsRegister(); | ||
| return true; | ||
| case 's': | ||
| // Relocatable constant. | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| void getTargetDefines(const LangOptions &Opts, | ||
| MacroBuilder &Builder) const override; | ||
|
|
||
| bool isCLZForZeroUndef() const override { return false; } | ||
|
|
||
| bool hasFeature(StringRef Feature) const override; | ||
|
|
||
| bool | ||
| initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, | ||
| StringRef CPU, | ||
| const std::vector<std::string> &FeaturesVec) const override; | ||
|
|
||
| bool handleTargetFeatures(std::vector<std::string> &Features, | ||
| DiagnosticsEngine &Diags) override; | ||
|
|
||
| void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name, | ||
| bool Enabled) const override; | ||
|
|
||
| BuiltinVaListKind getBuiltinVaListKind() const override { | ||
| return TargetInfo::CharPtrBuiltinVaList; | ||
| } | ||
|
|
||
| ArrayRef<const char *> getGCCRegNames() const override; | ||
|
|
||
| ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override; | ||
|
|
||
| const char *getClobbers() const override { return ""; } | ||
|
|
||
| static const char *getHexagonCPUSuffix(StringRef Name); | ||
|
|
||
| bool isValidCPUName(StringRef Name) const override { | ||
| return getHexagonCPUSuffix(Name); | ||
| } | ||
|
|
||
| bool setCPU(const std::string &Name) override { | ||
| if (!isValidCPUName(Name)) | ||
| return false; | ||
| CPU = Name; | ||
| return true; | ||
| } | ||
|
|
||
| int getEHDataRegisterNumber(unsigned RegNo) const override { | ||
| return RegNo < 2 ? RegNo : -1; | ||
| } | ||
| }; | ||
| } // namespace targets | ||
| } // namespace clang | ||
| #endif // LLVM_CLANG_LIB_BASIC_TARGETS_HEXAGON_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| //===--- Lanai.cpp - Implement Lanai target feature support ---------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file implements Lanai TargetInfo objects. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "Lanai.h" | ||
| #include "clang/Basic/MacroBuilder.h" | ||
| #include "llvm/ADT/StringSwitch.h" | ||
|
|
||
| using namespace clang; | ||
| using namespace clang::targets; | ||
|
|
||
| const char *const LanaiTargetInfo::GCCRegNames[] = { | ||
| "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", | ||
| "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", | ||
| "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" | ||
| }; | ||
|
|
||
| ArrayRef<const char *> LanaiTargetInfo::getGCCRegNames() const { | ||
| return llvm::makeArrayRef(GCCRegNames); | ||
| } | ||
|
|
||
| const TargetInfo::GCCRegAlias LanaiTargetInfo::GCCRegAliases[] = { | ||
| {{"pc"}, "r2"}, {{"sp"}, "r4"}, {{"fp"}, "r5"}, {{"rv"}, "r8"}, | ||
| {{"rr1"}, "r10"}, {{"rr2"}, "r11"}, {{"rca"}, "r15"}, | ||
| }; | ||
|
|
||
| ArrayRef<TargetInfo::GCCRegAlias> LanaiTargetInfo::getGCCRegAliases() const { | ||
| return llvm::makeArrayRef(GCCRegAliases); | ||
| } | ||
|
|
||
| bool LanaiTargetInfo::isValidCPUName(StringRef Name) const { | ||
| return llvm::StringSwitch<bool>(Name).Case("v11", true).Default(false); | ||
| } | ||
|
|
||
| bool LanaiTargetInfo::setCPU(const std::string &Name) { | ||
| CPU = llvm::StringSwitch<CPUKind>(Name).Case("v11", CK_V11).Default(CK_NONE); | ||
|
|
||
| return CPU != CK_NONE; | ||
| } | ||
|
|
||
| bool LanaiTargetInfo::hasFeature(StringRef Feature) const { | ||
| return llvm::StringSwitch<bool>(Feature).Case("lanai", true).Default(false); | ||
| } | ||
|
|
||
| void LanaiTargetInfo::getTargetDefines(const LangOptions &Opts, | ||
| MacroBuilder &Builder) const { | ||
| // Define __lanai__ when building for target lanai. | ||
| Builder.defineMacro("__lanai__"); | ||
|
|
||
| // Set define for the CPU specified. | ||
| switch (CPU) { | ||
| case CK_V11: | ||
| Builder.defineMacro("__LANAI_V11__"); | ||
| break; | ||
| case CK_NONE: | ||
| llvm_unreachable("Unhandled target CPU"); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| //===--- Lanai.h - Declare Lanai target feature support ---------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file declares Lanai TargetInfo objects. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_LANAI_H | ||
| #define LLVM_CLANG_LIB_BASIC_TARGETS_LANAI_H | ||
|
|
||
| #include "clang/Basic/TargetInfo.h" | ||
| #include "clang/Basic/TargetOptions.h" | ||
| #include "llvm/ADT/Triple.h" | ||
| #include "llvm/Support/Compiler.h" | ||
|
|
||
| namespace clang { | ||
| namespace targets { | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY LanaiTargetInfo : public TargetInfo { | ||
| // Class for Lanai (32-bit). | ||
| // The CPU profiles supported by the Lanai backend | ||
| enum CPUKind { | ||
| CK_NONE, | ||
| CK_V11, | ||
| } CPU; | ||
|
|
||
| static const TargetInfo::GCCRegAlias GCCRegAliases[]; | ||
| static const char *const GCCRegNames[]; | ||
|
|
||
| public: | ||
| LanaiTargetInfo(const llvm::Triple &Triple, const TargetOptions &) | ||
| : TargetInfo(Triple) { | ||
| // Description string has to be kept in sync with backend. | ||
| resetDataLayout("E" // Big endian | ||
| "-m:e" // ELF name manging | ||
| "-p:32:32" // 32 bit pointers, 32 bit aligned | ||
| "-i64:64" // 64 bit integers, 64 bit aligned | ||
| "-a:0:32" // 32 bit alignment of objects of aggregate type | ||
| "-n32" // 32 bit native integer width | ||
| "-S64" // 64 bit natural stack alignment | ||
| ); | ||
|
|
||
| // Setting RegParmMax equal to what mregparm was set to in the old | ||
| // toolchain | ||
| RegParmMax = 4; | ||
|
|
||
| // Set the default CPU to V11 | ||
| CPU = CK_V11; | ||
|
|
||
| // Temporary approach to make everything at least word-aligned and allow for | ||
| // safely casting between pointers with different alignment requirements. | ||
| // TODO: Remove this when there are no more cast align warnings on the | ||
| // firmware. | ||
| MinGlobalAlign = 32; | ||
| } | ||
|
|
||
| void getTargetDefines(const LangOptions &Opts, | ||
| MacroBuilder &Builder) const override; | ||
|
|
||
| bool isValidCPUName(StringRef Name) const override; | ||
|
|
||
| bool setCPU(const std::string &Name) override; | ||
|
|
||
| bool hasFeature(StringRef Feature) const override; | ||
|
|
||
| ArrayRef<const char *> getGCCRegNames() const override; | ||
|
|
||
| ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override; | ||
|
|
||
| BuiltinVaListKind getBuiltinVaListKind() const override { | ||
| return TargetInfo::VoidPtrBuiltinVaList; | ||
| } | ||
|
|
||
| ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; } | ||
|
|
||
| bool validateAsmConstraint(const char *&Name, | ||
| TargetInfo::ConstraintInfo &info) const override { | ||
| return false; | ||
| } | ||
|
|
||
| const char *getClobbers() const override { return ""; } | ||
| }; | ||
| } // namespace targets | ||
| } // namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_LIB_BASIC_TARGETS_LANAI_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| //===--- Le64.cpp - Implement Le64 target feature support -----------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file implements Le64 TargetInfo objects. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "Le64.h" | ||
| #include "Targets.h" | ||
| #include "clang/Basic/Builtins.h" | ||
| #include "clang/Basic/MacroBuilder.h" | ||
| #include "clang/Basic/TargetBuiltins.h" | ||
|
|
||
| using namespace clang; | ||
| using namespace clang::targets; | ||
|
|
||
| const Builtin::Info Le64TargetInfo::BuiltinInfo[] = { | ||
| #define BUILTIN(ID, TYPE, ATTRS) \ | ||
| {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, | ||
| #include "clang/Basic/BuiltinsLe64.def" | ||
| }; | ||
|
|
||
| ArrayRef<Builtin::Info> Le64TargetInfo::getTargetBuiltins() const { | ||
| return llvm::makeArrayRef(BuiltinInfo, clang::Le64::LastTSBuiltin - | ||
| Builtin::FirstTSBuiltin); | ||
| } | ||
|
|
||
| void Le64TargetInfo::getTargetDefines(const LangOptions &Opts, | ||
| MacroBuilder &Builder) const { | ||
| DefineStd(Builder, "unix", Opts); | ||
| defineCPUMacros(Builder, "le64", /*Tuning=*/false); | ||
| Builder.defineMacro("__ELF__"); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| //===--- Le64.h - Declare Le64 target feature support -----------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file declares Le64 TargetInfo objects. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_LE64_H | ||
| #define LLVM_CLANG_LIB_BASIC_TARGETS_LE64_H | ||
|
|
||
| #include "clang/Basic/TargetInfo.h" | ||
| #include "clang/Basic/TargetOptions.h" | ||
| #include "llvm/ADT/Triple.h" | ||
| #include "llvm/Support/Compiler.h" | ||
|
|
||
| namespace clang { | ||
| namespace targets { | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY Le64TargetInfo : public TargetInfo { | ||
| static const Builtin::Info BuiltinInfo[]; | ||
|
|
||
| public: | ||
| Le64TargetInfo(const llvm::Triple &Triple, const TargetOptions &) | ||
| : TargetInfo(Triple) { | ||
| NoAsmVariants = true; | ||
| LongWidth = LongAlign = PointerWidth = PointerAlign = 64; | ||
| MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; | ||
| resetDataLayout("e-m:e-v128:32-v16:16-v32:32-v96:32-n8:16:32:64-S128"); | ||
| } | ||
|
|
||
| void getTargetDefines(const LangOptions &Opts, | ||
| MacroBuilder &Builder) const override; | ||
|
|
||
| ArrayRef<Builtin::Info> getTargetBuiltins() const override; | ||
|
|
||
| BuiltinVaListKind getBuiltinVaListKind() const override { | ||
| return TargetInfo::PNaClABIBuiltinVaList; | ||
| } | ||
|
|
||
| const char *getClobbers() const override { return ""; } | ||
|
|
||
| ArrayRef<const char *> getGCCRegNames() const override { return None; } | ||
|
|
||
| ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { | ||
| return None; | ||
| } | ||
|
|
||
| bool validateAsmConstraint(const char *&Name, | ||
| TargetInfo::ConstraintInfo &Info) const override { | ||
| return false; | ||
| } | ||
|
|
||
| bool hasProtectedVisibility() const override { return false; } | ||
| }; | ||
|
|
||
| } // namespace targets | ||
| } // namespace clang | ||
| #endif // LLVM_CLANG_LIB_BASIC_TARGETS_LE64_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| //===--- MSP430.cpp - Implement MSP430 target feature support -------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file implements MSP430 TargetInfo objects. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "MSP430.h" | ||
| #include "clang/Basic/MacroBuilder.h" | ||
|
|
||
| using namespace clang; | ||
| using namespace clang::targets; | ||
|
|
||
| const char *const MSP430TargetInfo::GCCRegNames[] = { | ||
| "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", | ||
| "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" | ||
| }; | ||
|
|
||
| ArrayRef<const char *> MSP430TargetInfo::getGCCRegNames() const { | ||
| return llvm::makeArrayRef(GCCRegNames); | ||
| } | ||
|
|
||
| void MSP430TargetInfo::getTargetDefines(const LangOptions &Opts, | ||
| MacroBuilder &Builder) const { | ||
| Builder.defineMacro("MSP430"); | ||
| Builder.defineMacro("__MSP430__"); | ||
| // FIXME: defines for different 'flavours' of MCU | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| //===--- MSP430.h - Declare MSP430 target feature support -------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file declares MSP430 TargetInfo objects. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_MSP430_H | ||
| #define LLVM_CLANG_LIB_BASIC_TARGETS_MSP430_H | ||
|
|
||
| #include "clang/Basic/TargetInfo.h" | ||
| #include "clang/Basic/TargetOptions.h" | ||
| #include "llvm/ADT/Triple.h" | ||
| #include "llvm/Support/Compiler.h" | ||
|
|
||
| namespace clang { | ||
| namespace targets { | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY MSP430TargetInfo : public TargetInfo { | ||
| static const char *const GCCRegNames[]; | ||
|
|
||
| public: | ||
| MSP430TargetInfo(const llvm::Triple &Triple, const TargetOptions &) | ||
| : TargetInfo(Triple) { | ||
| TLSSupported = false; | ||
| IntWidth = 16; | ||
| IntAlign = 16; | ||
| LongWidth = 32; | ||
| LongLongWidth = 64; | ||
| LongAlign = LongLongAlign = 16; | ||
| PointerWidth = 16; | ||
| PointerAlign = 16; | ||
| SuitableAlign = 16; | ||
| SizeType = UnsignedInt; | ||
| IntMaxType = SignedLongLong; | ||
| IntPtrType = SignedInt; | ||
| PtrDiffType = SignedInt; | ||
| SigAtomicType = SignedLong; | ||
| resetDataLayout("e-m:e-p:16:16-i32:16-i64:16-f32:16-f64:16-a:8-n8:16-S16"); | ||
| } | ||
| void getTargetDefines(const LangOptions &Opts, | ||
| MacroBuilder &Builder) const override; | ||
|
|
||
| ArrayRef<Builtin::Info> getTargetBuiltins() const override { | ||
| // FIXME: Implement. | ||
| return None; | ||
| } | ||
|
|
||
| bool hasFeature(StringRef Feature) const override { | ||
| return Feature == "msp430"; | ||
| } | ||
|
|
||
| ArrayRef<const char *> getGCCRegNames() const override; | ||
|
|
||
| ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { | ||
| // No aliases. | ||
| return None; | ||
| } | ||
|
|
||
| bool validateAsmConstraint(const char *&Name, | ||
| TargetInfo::ConstraintInfo &info) const override { | ||
| // FIXME: implement | ||
| switch (*Name) { | ||
| case 'K': // the constant 1 | ||
| case 'L': // constant -1^20 .. 1^19 | ||
| case 'M': // constant 1-4: | ||
| return true; | ||
| } | ||
| // No target constraints for now. | ||
| return false; | ||
| } | ||
|
|
||
| const char *getClobbers() const override { | ||
| // FIXME: Is this really right? | ||
| return ""; | ||
| } | ||
|
|
||
| BuiltinVaListKind getBuiltinVaListKind() const override { | ||
| // FIXME: implement | ||
| return TargetInfo::CharPtrBuiltinVaList; | ||
| } | ||
| }; | ||
|
|
||
| } // namespace targets | ||
| } // namespace clang | ||
| #endif // LLVM_CLANG_LIB_BASIC_TARGETS_MSP430_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,242 @@ | ||
| //===--- Mips.cpp - Implement Mips target feature support -----------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file implements Mips TargetInfo objects. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "Mips.h" | ||
| #include "Targets.h" | ||
| #include "clang/Basic/Diagnostic.h" | ||
| #include "clang/Basic/MacroBuilder.h" | ||
| #include "clang/Basic/TargetBuiltins.h" | ||
| #include "llvm/ADT/StringSwitch.h" | ||
|
|
||
| using namespace clang; | ||
| using namespace clang::targets; | ||
|
|
||
| const Builtin::Info MipsTargetInfo::BuiltinInfo[] = { | ||
| #define BUILTIN(ID, TYPE, ATTRS) \ | ||
| {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, | ||
| #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ | ||
| {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, | ||
| #include "clang/Basic/BuiltinsMips.def" | ||
| }; | ||
|
|
||
| bool MipsTargetInfo::processorSupportsGPR64() const { | ||
| return llvm::StringSwitch<bool>(CPU) | ||
| .Case("mips3", true) | ||
| .Case("mips4", true) | ||
| .Case("mips5", true) | ||
| .Case("mips64", true) | ||
| .Case("mips64r2", true) | ||
| .Case("mips64r3", true) | ||
| .Case("mips64r5", true) | ||
| .Case("mips64r6", true) | ||
| .Case("octeon", true) | ||
| .Default(false); | ||
| return false; | ||
| } | ||
|
|
||
| bool MipsTargetInfo::isValidCPUName(StringRef Name) const { | ||
| return llvm::StringSwitch<bool>(Name) | ||
| .Case("mips1", true) | ||
| .Case("mips2", true) | ||
| .Case("mips3", true) | ||
| .Case("mips4", true) | ||
| .Case("mips5", true) | ||
| .Case("mips32", true) | ||
| .Case("mips32r2", true) | ||
| .Case("mips32r3", true) | ||
| .Case("mips32r5", true) | ||
| .Case("mips32r6", true) | ||
| .Case("mips64", true) | ||
| .Case("mips64r2", true) | ||
| .Case("mips64r3", true) | ||
| .Case("mips64r5", true) | ||
| .Case("mips64r6", true) | ||
| .Case("octeon", true) | ||
| .Case("p5600", true) | ||
| .Default(false); | ||
| } | ||
|
|
||
| void MipsTargetInfo::getTargetDefines(const LangOptions &Opts, | ||
| MacroBuilder &Builder) const { | ||
| if (BigEndian) { | ||
| DefineStd(Builder, "MIPSEB", Opts); | ||
| Builder.defineMacro("_MIPSEB"); | ||
| } else { | ||
| DefineStd(Builder, "MIPSEL", Opts); | ||
| Builder.defineMacro("_MIPSEL"); | ||
| } | ||
|
|
||
| Builder.defineMacro("__mips__"); | ||
| Builder.defineMacro("_mips"); | ||
| if (Opts.GNUMode) | ||
| Builder.defineMacro("mips"); | ||
|
|
||
| if (ABI == "o32") { | ||
| Builder.defineMacro("__mips", "32"); | ||
| Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS32"); | ||
| } else { | ||
| Builder.defineMacro("__mips", "64"); | ||
| Builder.defineMacro("__mips64"); | ||
| Builder.defineMacro("__mips64__"); | ||
| Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS64"); | ||
| } | ||
|
|
||
| const std::string ISARev = llvm::StringSwitch<std::string>(getCPU()) | ||
| .Cases("mips32", "mips64", "1") | ||
| .Cases("mips32r2", "mips64r2", "2") | ||
| .Cases("mips32r3", "mips64r3", "3") | ||
| .Cases("mips32r5", "mips64r5", "5") | ||
| .Cases("mips32r6", "mips64r6", "6") | ||
| .Default(""); | ||
| if (!ISARev.empty()) | ||
| Builder.defineMacro("__mips_isa_rev", ISARev); | ||
|
|
||
| if (ABI == "o32") { | ||
| Builder.defineMacro("__mips_o32"); | ||
| Builder.defineMacro("_ABIO32", "1"); | ||
| Builder.defineMacro("_MIPS_SIM", "_ABIO32"); | ||
| } else if (ABI == "n32") { | ||
| Builder.defineMacro("__mips_n32"); | ||
| Builder.defineMacro("_ABIN32", "2"); | ||
| Builder.defineMacro("_MIPS_SIM", "_ABIN32"); | ||
| } else if (ABI == "n64") { | ||
| Builder.defineMacro("__mips_n64"); | ||
| Builder.defineMacro("_ABI64", "3"); | ||
| Builder.defineMacro("_MIPS_SIM", "_ABI64"); | ||
| } else | ||
| llvm_unreachable("Invalid ABI."); | ||
|
|
||
| if (!IsNoABICalls) { | ||
| Builder.defineMacro("__mips_abicalls"); | ||
| if (CanUseBSDABICalls) | ||
| Builder.defineMacro("__ABICALLS__"); | ||
| } | ||
|
|
||
| Builder.defineMacro("__REGISTER_PREFIX__", ""); | ||
|
|
||
| switch (FloatABI) { | ||
| case HardFloat: | ||
| Builder.defineMacro("__mips_hard_float", Twine(1)); | ||
| break; | ||
| case SoftFloat: | ||
| Builder.defineMacro("__mips_soft_float", Twine(1)); | ||
| break; | ||
| } | ||
|
|
||
| if (IsSingleFloat) | ||
| Builder.defineMacro("__mips_single_float", Twine(1)); | ||
|
|
||
| Builder.defineMacro("__mips_fpr", HasFP64 ? Twine(64) : Twine(32)); | ||
| Builder.defineMacro("_MIPS_FPSET", | ||
| Twine(32 / (HasFP64 || IsSingleFloat ? 1 : 2))); | ||
|
|
||
| if (IsMips16) | ||
| Builder.defineMacro("__mips16", Twine(1)); | ||
|
|
||
| if (IsMicromips) | ||
| Builder.defineMacro("__mips_micromips", Twine(1)); | ||
|
|
||
| if (IsNan2008) | ||
| Builder.defineMacro("__mips_nan2008", Twine(1)); | ||
|
|
||
| switch (DspRev) { | ||
| default: | ||
| break; | ||
| case DSP1: | ||
| Builder.defineMacro("__mips_dsp_rev", Twine(1)); | ||
| Builder.defineMacro("__mips_dsp", Twine(1)); | ||
| break; | ||
| case DSP2: | ||
| Builder.defineMacro("__mips_dsp_rev", Twine(2)); | ||
| Builder.defineMacro("__mips_dspr2", Twine(1)); | ||
| Builder.defineMacro("__mips_dsp", Twine(1)); | ||
| break; | ||
| } | ||
|
|
||
| if (HasMSA) | ||
| Builder.defineMacro("__mips_msa", Twine(1)); | ||
|
|
||
| if (DisableMadd4) | ||
| Builder.defineMacro("__mips_no_madd4", Twine(1)); | ||
|
|
||
| Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(0))); | ||
| Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth())); | ||
| Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth())); | ||
|
|
||
| Builder.defineMacro("_MIPS_ARCH", "\"" + CPU + "\""); | ||
| Builder.defineMacro("_MIPS_ARCH_" + StringRef(CPU).upper()); | ||
|
|
||
| // These shouldn't be defined for MIPS-I but there's no need to check | ||
| // for that since MIPS-I isn't supported. | ||
| 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"); | ||
|
|
||
| // 32-bit MIPS processors don't have the necessary lld/scd instructions | ||
| // found in 64-bit processors. In the case of O32 on a 64-bit processor, | ||
| // the instructions exist but using them violates the ABI since they | ||
| // require 64-bit GPRs and O32 only supports 32-bit GPRs. | ||
| if (ABI == "n32" || ABI == "n64") | ||
| Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); | ||
| } | ||
|
|
||
| bool MipsTargetInfo::hasFeature(StringRef Feature) const { | ||
| return llvm::StringSwitch<bool>(Feature) | ||
| .Case("mips", true) | ||
| .Case("fp64", HasFP64) | ||
| .Default(false); | ||
| } | ||
|
|
||
| ArrayRef<Builtin::Info> MipsTargetInfo::getTargetBuiltins() const { | ||
| return llvm::makeArrayRef(BuiltinInfo, clang::Mips::LastTSBuiltin - | ||
| Builtin::FirstTSBuiltin); | ||
| } | ||
|
|
||
| bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const { | ||
| // FIXME: It's valid to use O32 on a 64-bit CPU but the backend can't handle | ||
| // this yet. It's better to fail here than on the backend assertion. | ||
| if (processorSupportsGPR64() && ABI == "o32") { | ||
| Diags.Report(diag::err_target_unsupported_abi) << ABI << CPU; | ||
| return false; | ||
| } | ||
|
|
||
| // 64-bit ABI's require 64-bit CPU's. | ||
| if (!processorSupportsGPR64() && (ABI == "n32" || ABI == "n64")) { | ||
| Diags.Report(diag::err_target_unsupported_abi) << ABI << CPU; | ||
| return false; | ||
| } | ||
|
|
||
| // FIXME: It's valid to use O32 on a mips64/mips64el triple but the backend | ||
| // can't handle this yet. It's better to fail here than on the | ||
| // backend assertion. | ||
| if ((getTriple().getArch() == llvm::Triple::mips64 || | ||
| getTriple().getArch() == llvm::Triple::mips64el) && | ||
| ABI == "o32") { | ||
| Diags.Report(diag::err_target_unsupported_abi_for_triple) | ||
| << ABI << getTriple().str(); | ||
| return false; | ||
| } | ||
|
|
||
| // FIXME: It's valid to use N32/N64 on a mips/mipsel triple but the backend | ||
| // can't handle this yet. It's better to fail here than on the | ||
| // backend assertion. | ||
| if ((getTriple().getArch() == llvm::Triple::mips || | ||
| getTriple().getArch() == llvm::Triple::mipsel) && | ||
| (ABI == "n32" || ABI == "n64")) { | ||
| Diags.Report(diag::err_target_unsupported_abi_for_triple) | ||
| << ABI << getTriple().str(); | ||
| return false; | ||
| } | ||
|
|
||
| return true; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,391 @@ | ||
| //===--- Mips.h - Declare Mips target feature support -----------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file declares Mips TargetInfo objects. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_MIPS_H | ||
| #define LLVM_CLANG_LIB_BASIC_TARGETS_MIPS_H | ||
|
|
||
| #include "clang/Basic/TargetInfo.h" | ||
| #include "clang/Basic/TargetOptions.h" | ||
| #include "llvm/ADT/Triple.h" | ||
| #include "llvm/Support/Compiler.h" | ||
|
|
||
| namespace clang { | ||
| namespace targets { | ||
|
|
||
| class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo { | ||
| void setDataLayout() { | ||
| StringRef Layout; | ||
|
|
||
| if (ABI == "o32") | ||
| Layout = "m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64"; | ||
| else if (ABI == "n32") | ||
| Layout = "m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128"; | ||
| else if (ABI == "n64") | ||
| Layout = "m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128"; | ||
| else | ||
| llvm_unreachable("Invalid ABI"); | ||
|
|
||
| if (BigEndian) | ||
| resetDataLayout(("E-" + Layout).str()); | ||
| else | ||
| resetDataLayout(("e-" + Layout).str()); | ||
| } | ||
|
|
||
| static const Builtin::Info BuiltinInfo[]; | ||
| std::string CPU; | ||
| bool IsMips16; | ||
| bool IsMicromips; | ||
| bool IsNan2008; | ||
| bool IsSingleFloat; | ||
| bool IsNoABICalls; | ||
| bool CanUseBSDABICalls; | ||
| enum MipsFloatABI { HardFloat, SoftFloat } FloatABI; | ||
| enum DspRevEnum { NoDSP, DSP1, DSP2 } DspRev; | ||
| bool HasMSA; | ||
| bool DisableMadd4; | ||
|
|
||
| protected: | ||
| bool HasFP64; | ||
| std::string ABI; | ||
|
|
||
| public: | ||
| MipsTargetInfo(const llvm::Triple &Triple, const TargetOptions &) | ||
| : TargetInfo(Triple), IsMips16(false), IsMicromips(false), | ||
| IsNan2008(false), IsSingleFloat(false), IsNoABICalls(false), | ||
| CanUseBSDABICalls(false), FloatABI(HardFloat), DspRev(NoDSP), | ||
| HasMSA(false), DisableMadd4(false), HasFP64(false) { | ||
| TheCXXABI.set(TargetCXXABI::GenericMIPS); | ||
|
|
||
| setABI((getTriple().getArch() == llvm::Triple::mips || | ||
| getTriple().getArch() == llvm::Triple::mipsel) | ||
| ? "o32" | ||
| : "n64"); | ||
|
|
||
| CPU = ABI == "o32" ? "mips32r2" : "mips64r2"; | ||
|
|
||
| CanUseBSDABICalls = Triple.getOS() == llvm::Triple::FreeBSD || | ||
| Triple.getOS() == llvm::Triple::OpenBSD; | ||
| } | ||
|
|
||
| bool isNaN2008Default() const { | ||
| return CPU == "mips32r6" || CPU == "mips64r6"; | ||
| } | ||
|
|
||
| bool isFP64Default() const { | ||
| return CPU == "mips32r6" || ABI == "n32" || ABI == "n64" || ABI == "64"; | ||
| } | ||
|
|
||
| bool isNan2008() const override { return IsNan2008; } | ||
|
|
||
| bool processorSupportsGPR64() const; | ||
|
|
||
| StringRef getABI() const override { return ABI; } | ||
|
|
||
| bool setABI(const std::string &Name) override { | ||
| if (Name == "o32") { | ||
| setO32ABITypes(); | ||
| ABI = Name; | ||
| return true; | ||
| } | ||
|
|
||
| if (Name == "n32") { | ||
| setN32ABITypes(); | ||
| ABI = Name; | ||
| return true; | ||
| } | ||
| if (Name == "n64") { | ||
| setN64ABITypes(); | ||
| ABI = Name; | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| void setO32ABITypes() { | ||
| Int64Type = SignedLongLong; | ||
| IntMaxType = Int64Type; | ||
| LongDoubleFormat = &llvm::APFloat::IEEEdouble(); | ||
| LongDoubleWidth = LongDoubleAlign = 64; | ||
| LongWidth = LongAlign = 32; | ||
| MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32; | ||
| PointerWidth = PointerAlign = 32; | ||
| PtrDiffType = SignedInt; | ||
| SizeType = UnsignedInt; | ||
| SuitableAlign = 64; | ||
| } | ||
|
|
||
| void setN32N64ABITypes() { | ||
| LongDoubleWidth = LongDoubleAlign = 128; | ||
| LongDoubleFormat = &llvm::APFloat::IEEEquad(); | ||
| if (getTriple().getOS() == llvm::Triple::FreeBSD) { | ||
| LongDoubleWidth = LongDoubleAlign = 64; | ||
| LongDoubleFormat = &llvm::APFloat::IEEEdouble(); | ||
| } | ||
| MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; | ||
| SuitableAlign = 128; | ||
| } | ||
|
|
||
| void setN64ABITypes() { | ||
| setN32N64ABITypes(); | ||
| if (getTriple().getOS() == llvm::Triple::OpenBSD) { | ||
| Int64Type = SignedLongLong; | ||
| } else { | ||
| Int64Type = SignedLong; | ||
| } | ||
| IntMaxType = Int64Type; | ||
| LongWidth = LongAlign = 64; | ||
| PointerWidth = PointerAlign = 64; | ||
| PtrDiffType = SignedLong; | ||
| SizeType = UnsignedLong; | ||
| } | ||
|
|
||
| void setN32ABITypes() { | ||
| setN32N64ABITypes(); | ||
| Int64Type = SignedLongLong; | ||
| IntMaxType = Int64Type; | ||
| LongWidth = LongAlign = 32; | ||
| PointerWidth = PointerAlign = 32; | ||
| PtrDiffType = SignedInt; | ||
| SizeType = UnsignedInt; | ||
| } | ||
|
|
||
| bool isValidCPUName(StringRef Name) const override; | ||
|
|
||
| bool setCPU(const std::string &Name) override { | ||
| CPU = Name; | ||
| return isValidCPUName(Name); | ||
| } | ||
|
|
||
| const std::string &getCPU() const { return CPU; } | ||
| bool | ||
| initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, | ||
| StringRef CPU, | ||
| const std::vector<std::string> &FeaturesVec) const override { | ||
| if (CPU.empty()) | ||
| CPU = getCPU(); | ||
| if (CPU == "octeon") | ||
| Features["mips64r2"] = Features["cnmips"] = true; | ||
| else | ||
| Features[CPU] = true; | ||
| return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); | ||
| } | ||
|
|
||
| void getTargetDefines(const LangOptions &Opts, | ||
| MacroBuilder &Builder) const override; | ||
|
|
||
| ArrayRef<Builtin::Info> getTargetBuiltins() const override; | ||
|
|
||
| bool hasFeature(StringRef Feature) const override; | ||
|
|
||
| BuiltinVaListKind getBuiltinVaListKind() const override { | ||
| return TargetInfo::VoidPtrBuiltinVaList; | ||
| } | ||
|
|
||
| ArrayRef<const char *> getGCCRegNames() const override { | ||
| static const char *const GCCRegNames[] = { | ||
| // CPU register names | ||
| // Must match second column of GCCRegAliases | ||
| "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", | ||
| "$11", "$12", "$13", "$14", "$15", "$16", "$17", "$18", "$19", "$20", | ||
| "$21", "$22", "$23", "$24", "$25", "$26", "$27", "$28", "$29", "$30", | ||
| "$31", | ||
| // Floating point register names | ||
| "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", "$f8", "$f9", | ||
| "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", "$f16", "$f17", "$f18", | ||
| "$f19", "$f20", "$f21", "$f22", "$f23", "$f24", "$f25", "$f26", "$f27", | ||
| "$f28", "$f29", "$f30", "$f31", | ||
| // Hi/lo and condition register names | ||
| "hi", "lo", "", "$fcc0", "$fcc1", "$fcc2", "$fcc3", "$fcc4", "$fcc5", | ||
| "$fcc6", "$fcc7", "$ac1hi", "$ac1lo", "$ac2hi", "$ac2lo", "$ac3hi", | ||
| "$ac3lo", | ||
| // MSA register names | ||
| "$w0", "$w1", "$w2", "$w3", "$w4", "$w5", "$w6", "$w7", "$w8", "$w9", | ||
| "$w10", "$w11", "$w12", "$w13", "$w14", "$w15", "$w16", "$w17", "$w18", | ||
| "$w19", "$w20", "$w21", "$w22", "$w23", "$w24", "$w25", "$w26", "$w27", | ||
| "$w28", "$w29", "$w30", "$w31", | ||
| // MSA control register names | ||
| "$msair", "$msacsr", "$msaaccess", "$msasave", "$msamodify", | ||
| "$msarequest", "$msamap", "$msaunmap" | ||
| }; | ||
| return llvm::makeArrayRef(GCCRegNames); | ||
| } | ||
|
|
||
| bool validateAsmConstraint(const char *&Name, | ||
| TargetInfo::ConstraintInfo &Info) const override { | ||
| switch (*Name) { | ||
| default: | ||
| return false; | ||
| case 'r': // CPU registers. | ||
| case 'd': // Equivalent to "r" unless generating MIPS16 code. | ||
| case 'y': // Equivalent to "r", backward compatibility only. | ||
| case 'f': // floating-point registers. | ||
| case 'c': // $25 for indirect jumps | ||
| case 'l': // lo register | ||
| case 'x': // hilo register pair | ||
| Info.setAllowsRegister(); | ||
| return true; | ||
| case 'I': // Signed 16-bit constant | ||
| case 'J': // Integer 0 | ||
| case 'K': // Unsigned 16-bit constant | ||
| case 'L': // Signed 32-bit constant, lower 16-bit zeros (for lui) | ||
| case 'M': // Constants not loadable via lui, addiu, or ori | ||
| case 'N': // Constant -1 to -65535 | ||
| case 'O': // A signed 15-bit constant | ||
| case 'P': // A constant between 1 go 65535 | ||
| return true; | ||
| case 'R': // An address that can be used in a non-macro load or store | ||
| Info.setAllowsMemory(); | ||
| return true; | ||
| case 'Z': | ||
| if (Name[1] == 'C') { // An address usable by ll, and sc. | ||
| Info.setAllowsMemory(); | ||
| Name++; // Skip over 'Z'. | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| std::string convertConstraint(const char *&Constraint) const override { | ||
| std::string R; | ||
| switch (*Constraint) { | ||
| case 'Z': // Two-character constraint; add "^" hint for later parsing. | ||
| if (Constraint[1] == 'C') { | ||
| R = std::string("^") + std::string(Constraint, 2); | ||
| Constraint++; | ||
| return R; | ||
| } | ||
| break; | ||
| } | ||
| return TargetInfo::convertConstraint(Constraint); | ||
| } | ||
|
|
||
| const char *getClobbers() const override { | ||
| // In GCC, $1 is not widely used in generated code (it's used only in a few | ||
| // specific situations), so there is no real need for users to add it to | ||
| // the clobbers list if they want to use it in their inline assembly code. | ||
| // | ||
| // In LLVM, $1 is treated as a normal GPR and is always allocatable during | ||
| // code generation, so using it in inline assembly without adding it to the | ||
| // clobbers list can cause conflicts between the inline assembly code and | ||
| // the surrounding generated code. | ||
| // | ||
| // Another problem is that LLVM is allowed to choose $1 for inline assembly | ||
| // operands, which will conflict with the ".set at" assembler option (which | ||
| // we use only for inline assembly, in order to maintain compatibility with | ||
| // GCC) and will also conflict with the user's usage of $1. | ||
| // | ||
| // The easiest way to avoid these conflicts and keep $1 as an allocatable | ||
| // register for generated code is to automatically clobber $1 for all inline | ||
| // assembly code. | ||
| // | ||
| // FIXME: We should automatically clobber $1 only for inline assembly code | ||
| // which actually uses it. This would allow LLVM to use $1 for inline | ||
| // assembly operands if the user's assembly code doesn't use it. | ||
| return "~{$1}"; | ||
| } | ||
|
|
||
| bool handleTargetFeatures(std::vector<std::string> &Features, | ||
| DiagnosticsEngine &Diags) override { | ||
| IsMips16 = false; | ||
| IsMicromips = false; | ||
| IsNan2008 = isNaN2008Default(); | ||
| IsSingleFloat = false; | ||
| FloatABI = HardFloat; | ||
| DspRev = NoDSP; | ||
| HasFP64 = isFP64Default(); | ||
|
|
||
| for (const auto &Feature : Features) { | ||
| if (Feature == "+single-float") | ||
| IsSingleFloat = true; | ||
| else if (Feature == "+soft-float") | ||
| FloatABI = SoftFloat; | ||
| else if (Feature == "+mips16") | ||
| IsMips16 = true; | ||
| else if (Feature == "+micromips") | ||
| IsMicromips = true; | ||
| else if (Feature == "+dsp") | ||
| DspRev = std::max(DspRev, DSP1); | ||
| else if (Feature == "+dspr2") | ||
| DspRev = std::max(DspRev, DSP2); | ||
| else if (Feature == "+msa") | ||
| HasMSA = true; | ||
| else if (Feature == "+nomadd4") | ||
| DisableMadd4 = true; | ||
| else if (Feature == "+fp64") | ||
| HasFP64 = true; | ||
| else if (Feature == "-fp64") | ||
| HasFP64 = false; | ||
| else if (Feature == "+nan2008") | ||
| IsNan2008 = true; | ||
| else if (Feature == "-nan2008") | ||
| IsNan2008 = false; | ||
| else if (Feature == "+noabicalls") | ||
| IsNoABICalls = true; | ||
| } | ||
|
|
||
| setDataLayout(); | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| int getEHDataRegisterNumber(unsigned RegNo) const override { | ||
| if (RegNo == 0) | ||
| return 4; | ||
| if (RegNo == 1) | ||
| return 5; | ||
| return -1; | ||
| } | ||
|
|
||
| bool isCLZForZeroUndef() const override { return false; } | ||
|
|
||
| ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { | ||
| static const TargetInfo::GCCRegAlias O32RegAliases[] = { | ||
| {{"at"}, "$1"}, {{"v0"}, "$2"}, {{"v1"}, "$3"}, | ||
| {{"a0"}, "$4"}, {{"a1"}, "$5"}, {{"a2"}, "$6"}, | ||
| {{"a3"}, "$7"}, {{"t0"}, "$8"}, {{"t1"}, "$9"}, | ||
| {{"t2"}, "$10"}, {{"t3"}, "$11"}, {{"t4"}, "$12"}, | ||
| {{"t5"}, "$13"}, {{"t6"}, "$14"}, {{"t7"}, "$15"}, | ||
| {{"s0"}, "$16"}, {{"s1"}, "$17"}, {{"s2"}, "$18"}, | ||
| {{"s3"}, "$19"}, {{"s4"}, "$20"}, {{"s5"}, "$21"}, | ||
| {{"s6"}, "$22"}, {{"s7"}, "$23"}, {{"t8"}, "$24"}, | ||
| {{"t9"}, "$25"}, {{"k0"}, "$26"}, {{"k1"}, "$27"}, | ||
| {{"gp"}, "$28"}, {{"sp", "$sp"}, "$29"}, {{"fp", "$fp"}, "$30"}, | ||
| {{"ra"}, "$31"} | ||
| }; | ||
| static const TargetInfo::GCCRegAlias NewABIRegAliases[] = { | ||
| {{"at"}, "$1"}, {{"v0"}, "$2"}, {{"v1"}, "$3"}, | ||
| {{"a0"}, "$4"}, {{"a1"}, "$5"}, {{"a2"}, "$6"}, | ||
| {{"a3"}, "$7"}, {{"a4"}, "$8"}, {{"a5"}, "$9"}, | ||
| {{"a6"}, "$10"}, {{"a7"}, "$11"}, {{"t0"}, "$12"}, | ||
| {{"t1"}, "$13"}, {{"t2"}, "$14"}, {{"t3"}, "$15"}, | ||
| {{"s0"}, "$16"}, {{"s1"}, "$17"}, {{"s2"}, "$18"}, | ||
| {{"s3"}, "$19"}, {{"s4"}, "$20"}, {{"s5"}, "$21"}, | ||
| {{"s6"}, "$22"}, {{"s7"}, "$23"}, {{"t8"}, "$24"}, | ||
| {{"t9"}, "$25"}, {{"k0"}, "$26"}, {{"k1"}, "$27"}, | ||
| {{"gp"}, "$28"}, {{"sp", "$sp"}, "$29"}, {{"fp", "$fp"}, "$30"}, | ||
| {{"ra"}, "$31"} | ||
| }; | ||
| if (ABI == "o32") | ||
| return llvm::makeArrayRef(O32RegAliases); | ||
| return llvm::makeArrayRef(NewABIRegAliases); | ||
| } | ||
|
|
||
| bool hasInt128Type() const override { return ABI == "n32" || ABI == "n64"; } | ||
|
|
||
| bool validateTarget(DiagnosticsEngine &Diags) const override; | ||
| }; | ||
| } // namespace targets | ||
| } // namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_LIB_BASIC_TARGETS_MIPS_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,196 @@ | ||
| //===--- NVPTX.cpp - Implement NVPTX target feature support ---------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file implements NVPTX TargetInfo objects. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "NVPTX.h" | ||
| #include "Targets.h" | ||
| #include "clang/Basic/Builtins.h" | ||
| #include "clang/Basic/MacroBuilder.h" | ||
| #include "clang/Basic/TargetBuiltins.h" | ||
| #include "llvm/ADT/StringSwitch.h" | ||
|
|
||
| using namespace clang; | ||
| using namespace clang::targets; | ||
|
|
||
| const Builtin::Info NVPTXTargetInfo::BuiltinInfo[] = { | ||
| #define BUILTIN(ID, TYPE, ATTRS) \ | ||
| {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, | ||
| #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ | ||
| {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, | ||
| #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ | ||
| {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE}, | ||
| #include "clang/Basic/BuiltinsNVPTX.def" | ||
| }; | ||
|
|
||
| const char *const NVPTXTargetInfo::GCCRegNames[] = {"r0"}; | ||
|
|
||
| NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple, | ||
| const TargetOptions &Opts, | ||
| unsigned TargetPointerWidth) | ||
| : TargetInfo(Triple) { | ||
| assert((TargetPointerWidth == 32 || TargetPointerWidth == 64) && | ||
| "NVPTX only supports 32- and 64-bit modes."); | ||
|
|
||
| TLSSupported = false; | ||
| AddrSpaceMap = &NVPTXAddrSpaceMap; | ||
| UseAddrSpaceMapMangling = true; | ||
|
|
||
| // Define available target features | ||
| // These must be defined in sorted order! | ||
| NoAsmVariants = true; | ||
| GPU = CudaArch::SM_20; | ||
|
|
||
| if (TargetPointerWidth == 32) | ||
| resetDataLayout("e-p:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64"); | ||
| else | ||
| resetDataLayout("e-i64:64-i128:128-v16:16-v32:32-n16:32:64"); | ||
|
|
||
| // If possible, get a TargetInfo for our host triple, so we can match its | ||
| // types. | ||
| llvm::Triple HostTriple(Opts.HostTriple); | ||
| if (!HostTriple.isNVPTX()) | ||
| HostTarget.reset(AllocateTarget(llvm::Triple(Opts.HostTriple), Opts)); | ||
|
|
||
| // If no host target, make some guesses about the data layout and return. | ||
| if (!HostTarget) { | ||
| LongWidth = LongAlign = TargetPointerWidth; | ||
| PointerWidth = PointerAlign = TargetPointerWidth; | ||
| switch (TargetPointerWidth) { | ||
| case 32: | ||
| SizeType = TargetInfo::UnsignedInt; | ||
| PtrDiffType = TargetInfo::SignedInt; | ||
| IntPtrType = TargetInfo::SignedInt; | ||
| break; | ||
| case 64: | ||
| SizeType = TargetInfo::UnsignedLong; | ||
| PtrDiffType = TargetInfo::SignedLong; | ||
| IntPtrType = TargetInfo::SignedLong; | ||
| break; | ||
| default: | ||
| llvm_unreachable("TargetPointerWidth must be 32 or 64"); | ||
| } | ||
| return; | ||
| } | ||
|
|
||
| // Copy properties from host target. | ||
| PointerWidth = HostTarget->getPointerWidth(/* AddrSpace = */ 0); | ||
| PointerAlign = HostTarget->getPointerAlign(/* AddrSpace = */ 0); | ||
| BoolWidth = HostTarget->getBoolWidth(); | ||
| BoolAlign = HostTarget->getBoolAlign(); | ||
| IntWidth = HostTarget->getIntWidth(); | ||
| IntAlign = HostTarget->getIntAlign(); | ||
| HalfWidth = HostTarget->getHalfWidth(); | ||
| HalfAlign = HostTarget->getHalfAlign(); | ||
| FloatWidth = HostTarget->getFloatWidth(); | ||
| FloatAlign = HostTarget->getFloatAlign(); | ||
| DoubleWidth = HostTarget->getDoubleWidth(); | ||
| DoubleAlign = HostTarget->getDoubleAlign(); | ||
| LongWidth = HostTarget->getLongWidth(); | ||
| LongAlign = HostTarget->getLongAlign(); | ||
| LongLongWidth = HostTarget->getLongLongWidth(); | ||
| LongLongAlign = HostTarget->getLongLongAlign(); | ||
| MinGlobalAlign = HostTarget->getMinGlobalAlign(); | ||
| NewAlign = HostTarget->getNewAlign(); | ||
| DefaultAlignForAttributeAligned = | ||
| HostTarget->getDefaultAlignForAttributeAligned(); | ||
| SizeType = HostTarget->getSizeType(); | ||
| IntMaxType = HostTarget->getIntMaxType(); | ||
| PtrDiffType = HostTarget->getPtrDiffType(/* AddrSpace = */ 0); | ||
| IntPtrType = HostTarget->getIntPtrType(); | ||
| WCharType = HostTarget->getWCharType(); | ||
| WIntType = HostTarget->getWIntType(); | ||
| Char16Type = HostTarget->getChar16Type(); | ||
| Char32Type = HostTarget->getChar32Type(); | ||
| Int64Type = HostTarget->getInt64Type(); | ||
| SigAtomicType = HostTarget->getSigAtomicType(); | ||
| ProcessIDType = HostTarget->getProcessIDType(); | ||
|
|
||
| UseBitFieldTypeAlignment = HostTarget->useBitFieldTypeAlignment(); | ||
| UseZeroLengthBitfieldAlignment = HostTarget->useZeroLengthBitfieldAlignment(); | ||
| UseExplicitBitFieldAlignment = HostTarget->useExplicitBitFieldAlignment(); | ||
| ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary(); | ||
|
|
||
| // This is a bit of a lie, but it controls __GCC_ATOMIC_XXX_LOCK_FREE, and | ||
| // we need those macros to be identical on host and device, because (among | ||
| // other things) they affect which standard library classes are defined, and | ||
| // we need all classes to be defined on both the host and device. | ||
| MaxAtomicInlineWidth = HostTarget->getMaxAtomicInlineWidth(); | ||
|
|
||
| // Properties intentionally not copied from host: | ||
| // - LargeArrayMinWidth, LargeArrayAlign: Not visible across the | ||
| // host/device boundary. | ||
| // - SuitableAlign: Not visible across the host/device boundary, and may | ||
| // correctly be different on host/device, e.g. if host has wider vector | ||
| // types than device. | ||
| // - LongDoubleWidth, LongDoubleAlign: nvptx's long double type is the same | ||
| // as its double type, but that's not necessarily true on the host. | ||
| // TODO: nvcc emits a warning when using long double on device; we should | ||
| // do the same. | ||
| } | ||
|
|
||
| ArrayRef<const char *> NVPTXTargetInfo::getGCCRegNames() const { | ||
| return llvm::makeArrayRef(GCCRegNames); | ||
| } | ||
|
|
||
| bool NVPTXTargetInfo::hasFeature(StringRef Feature) const { | ||
| return llvm::StringSwitch<bool>(Feature) | ||
| .Cases("ptx", "nvptx", true) | ||
| .Case("satom", GPU >= CudaArch::SM_60) // Atomics w/ scope. | ||
| .Default(false); | ||
| } | ||
|
|
||
| void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts, | ||
| MacroBuilder &Builder) const { | ||
| Builder.defineMacro("__PTX__"); | ||
| Builder.defineMacro("__NVPTX__"); | ||
| if (Opts.CUDAIsDevice) { | ||
| // Set __CUDA_ARCH__ for the GPU specified. | ||
| std::string CUDAArchCode = [this] { | ||
| switch (GPU) { | ||
| case CudaArch::UNKNOWN: | ||
| assert(false && "No GPU arch when compiling CUDA device code."); | ||
| return ""; | ||
| case CudaArch::SM_20: | ||
| return "200"; | ||
| case CudaArch::SM_21: | ||
| return "210"; | ||
| case CudaArch::SM_30: | ||
| return "300"; | ||
| case CudaArch::SM_32: | ||
| return "320"; | ||
| case CudaArch::SM_35: | ||
| return "350"; | ||
| case CudaArch::SM_37: | ||
| return "370"; | ||
| case CudaArch::SM_50: | ||
| return "500"; | ||
| case CudaArch::SM_52: | ||
| return "520"; | ||
| case CudaArch::SM_53: | ||
| return "530"; | ||
| case CudaArch::SM_60: | ||
| return "600"; | ||
| case CudaArch::SM_61: | ||
| return "610"; | ||
| case CudaArch::SM_62: | ||
| return "620"; | ||
| } | ||
| llvm_unreachable("unhandled CudaArch"); | ||
| }(); | ||
| Builder.defineMacro("__CUDA_ARCH__", CUDAArchCode); | ||
| } | ||
| } | ||
|
|
||
| ArrayRef<Builtin::Info> NVPTXTargetInfo::getTargetBuiltins() const { | ||
| return llvm::makeArrayRef(BuiltinInfo, clang::NVPTX::LastTSBuiltin - | ||
| Builtin::FirstTSBuiltin); | ||
| } |