216 lines · cpp
1//===--- SystemZ.cpp - Implement SystemZ target feature support -----------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements SystemZ TargetInfo objects.10//11//===----------------------------------------------------------------------===//12 13#include "SystemZ.h"14#include "clang/Basic/Builtins.h"15#include "clang/Basic/LangOptions.h"16#include "clang/Basic/MacroBuilder.h"17#include "clang/Basic/TargetBuiltins.h"18#include "llvm/ADT/StringExtras.h"19#include "llvm/ADT/StringSwitch.h"20 21using namespace clang;22using namespace clang::targets;23 24static constexpr int NumBuiltins =25 clang::SystemZ::LastTSBuiltin - Builtin::FirstTSBuiltin;26 27static constexpr llvm::StringTable BuiltinStrings =28 CLANG_BUILTIN_STR_TABLE_START29#define BUILTIN CLANG_BUILTIN_STR_TABLE30#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE31#include "clang/Basic/BuiltinsSystemZ.def"32 ;33 34static constexpr auto BuiltinInfos = Builtin::MakeInfos<NumBuiltins>({35#define BUILTIN CLANG_BUILTIN_ENTRY36#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY37#include "clang/Basic/BuiltinsSystemZ.def"38});39 40const char *const SystemZTargetInfo::GCCRegNames[] = {41 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",42 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",43 "f0", "f2", "f4", "f6", "f1", "f3", "f5", "f7",44 "f8", "f10", "f12", "f14", "f9", "f11", "f13", "f15",45 /*ap*/"", "cc", /*fp*/"", /*rp*/"", "a0", "a1",46 "v16", "v18", "v20", "v22", "v17", "v19", "v21", "v23",47 "v24", "v26", "v28", "v30", "v25", "v27", "v29", "v31"48};49 50const TargetInfo::AddlRegName GCCAddlRegNames[] = {51 {{"v0"}, 16}, {{"v2"}, 17}, {{"v4"}, 18}, {{"v6"}, 19},52 {{"v1"}, 20}, {{"v3"}, 21}, {{"v5"}, 22}, {{"v7"}, 23},53 {{"v8"}, 24}, {{"v10"}, 25}, {{"v12"}, 26}, {{"v14"}, 27},54 {{"v9"}, 28}, {{"v11"}, 29}, {{"v13"}, 30}, {{"v15"}, 31}55};56 57ArrayRef<const char *> SystemZTargetInfo::getGCCRegNames() const {58 return llvm::ArrayRef(GCCRegNames);59}60 61ArrayRef<TargetInfo::AddlRegName> SystemZTargetInfo::getGCCAddlRegNames() const {62 return llvm::ArrayRef(GCCAddlRegNames);63}64 65bool SystemZTargetInfo::validateAsmConstraint(66 const char *&Name, TargetInfo::ConstraintInfo &Info) const {67 switch (*Name) {68 default:69 return false;70 71 case 'Z':72 switch (Name[1]) {73 default:74 return false;75 case 'Q': // Address with base and unsigned 12-bit displacement76 case 'R': // Likewise, plus an index77 case 'S': // Address with base and signed 20-bit displacement78 case 'T': // Likewise, plus an index79 break;80 }81 [[fallthrough]];82 case 'a': // Address register83 case 'd': // Data register (equivalent to 'r')84 case 'f': // Floating-point register85 case 'v': // Vector register86 Info.setAllowsRegister();87 return true;88 89 case 'I': // Unsigned 8-bit constant90 case 'J': // Unsigned 12-bit constant91 case 'K': // Signed 16-bit constant92 case 'L': // Signed 20-bit displacement (on all targets we support)93 case 'M': // 0x7fffffff94 return true;95 96 case 'Q': // Memory with base and unsigned 12-bit displacement97 case 'R': // Likewise, plus an index98 case 'S': // Memory with base and signed 20-bit displacement99 case 'T': // Likewise, plus an index100 Info.setAllowsMemory();101 return true;102 case '@':103 // CC condition changes.104 if (StringRef(Name) == "@cc") {105 Name += 2;106 Info.setAllowsRegister();107 // SystemZ has 2-bits CC, and hence Interval [0, 4).108 Info.setOutputOperandBounds(0, 4);109 return true;110 }111 return false;112 }113}114 115struct ISANameRevision {116 llvm::StringLiteral Name;117 int ISARevisionID;118};119static constexpr ISANameRevision ISARevisions[] = {120 {{"arch8"}, 8}, {{"z10"}, 8},121 {{"arch9"}, 9}, {{"z196"}, 9},122 {{"arch10"}, 10}, {{"zEC12"}, 10},123 {{"arch11"}, 11}, {{"z13"}, 11},124 {{"arch12"}, 12}, {{"z14"}, 12},125 {{"arch13"}, 13}, {{"z15"}, 13},126 {{"arch14"}, 14}, {{"z16"}, 14},127 {{"arch15"}, 15}, {{"z17"}, 15},128};129 130int SystemZTargetInfo::getISARevision(StringRef Name) const {131 const auto Rev =132 llvm::find_if(ISARevisions, [Name](const ISANameRevision &CR) {133 return CR.Name == Name;134 });135 if (Rev == std::end(ISARevisions))136 return -1;137 return Rev->ISARevisionID;138}139 140void SystemZTargetInfo::fillValidCPUList(141 SmallVectorImpl<StringRef> &Values) const {142 for (const ISANameRevision &Rev : ISARevisions)143 Values.push_back(Rev.Name);144}145 146bool SystemZTargetInfo::hasFeature(StringRef Feature) const {147 return llvm::StringSwitch<bool>(Feature)148 .Case("systemz", true)149 .Case("arch8", ISARevision >= 8)150 .Case("arch9", ISARevision >= 9)151 .Case("arch10", ISARevision >= 10)152 .Case("arch11", ISARevision >= 11)153 .Case("arch12", ISARevision >= 12)154 .Case("arch13", ISARevision >= 13)155 .Case("arch14", ISARevision >= 14)156 .Case("arch15", ISARevision >= 15)157 .Case("htm", HasTransactionalExecution)158 .Case("vx", HasVector)159 .Default(false);160}161 162unsigned SystemZTargetInfo::getMinGlobalAlign(uint64_t Size,163 bool HasNonWeakDef) const {164 // Don't enforce the minimum alignment on an external or weak symbol if165 // -munaligned-symbols is passed.166 if (UnalignedSymbols && !HasNonWeakDef)167 return 0;168 169 return MinGlobalAlign;170}171 172void SystemZTargetInfo::getTargetDefines(const LangOptions &Opts,173 MacroBuilder &Builder) const {174 // Inline assembly supports SystemZ flag outputs.175 Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__");176 177 Builder.defineMacro("__s390__");178 Builder.defineMacro("__s390x__");179 Builder.defineMacro("__zarch__");180 Builder.defineMacro("__LONG_DOUBLE_128__");181 182 Builder.defineMacro("__ARCH__", Twine(ISARevision));183 184 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");185 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");186 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");187 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");188 189 if (HasTransactionalExecution)190 Builder.defineMacro("__HTM__");191 if (HasVector)192 Builder.defineMacro("__VX__");193 if (Opts.ZVector)194 Builder.defineMacro("__VEC__", "10305");195 196 /* Set __TARGET_LIB__ only if a value was given. If no value was given */197 /* we rely on the LE headers to define __TARGET_LIB__. */198 if (!getTriple().getOSVersion().empty()) {199 llvm::VersionTuple V = getTriple().getOSVersion();200 // Create string with form: 0xPVRRMMMM, where P=4201 std::string Str("0x");202 unsigned int Librel = 0x40000000;203 Librel |= V.getMajor() << 24;204 Librel |= V.getMinor().value_or(1) << 16;205 Librel |= V.getSubminor().value_or(0);206 Str += llvm::utohexstr(Librel);207 208 Builder.defineMacro("__TARGET_LIB__", Str);209 }210}211 212llvm::SmallVector<Builtin::InfosShard>213SystemZTargetInfo::getTargetBuiltins() const {214 return {{&BuiltinStrings, BuiltinInfos}};215}216