brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.7 KiB · 3988cb5 Raw
258 lines · cpp
1//===--- M68k.cpp - Implement M68k targets 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 M68k TargetInfo objects.10//11//===----------------------------------------------------------------------===//12 13#include "M68k.h"14#include "clang/Basic/Builtins.h"15#include "clang/Basic/Diagnostic.h"16#include "llvm/ADT/StringRef.h"17#include "llvm/ADT/StringSwitch.h"18#include "llvm/TargetParser/TargetParser.h"19#include <cstdint>20#include <cstring>21#include <limits>22#include <optional>23 24namespace clang {25namespace targets {26 27M68kTargetInfo::M68kTargetInfo(const llvm::Triple &Triple,28                               const TargetOptions &Opts)29    : TargetInfo(Triple), TargetOpts(Opts) {30 31  std::string Layout;32 33  // M68k is Big Endian34  Layout += "E";35 36  // FIXME how to wire it with the used object format?37  Layout += "-m:e";38 39  // M68k pointers are always 32 bit wide even for 16-bit CPUs40  Layout += "-p:32:16:32";41 42  // M68k integer data types43  Layout += "-i8:8:8-i16:16:16-i32:16:32";44 45  // FIXME no floats at the moment46 47  // The registers can hold 8, 16, 32 bits48  Layout += "-n8:16:32";49 50  // 16 bit alignment for both stack and aggregate51  // in order to conform to ABI used by GCC52  Layout += "-a:0:16-S16";53 54  resetDataLayout(Layout);55 56  SizeType = UnsignedInt;57  PtrDiffType = SignedInt;58  IntPtrType = SignedInt;59  IntAlign = LongAlign = PointerAlign = 16;60}61 62bool M68kTargetInfo::setCPU(const std::string &Name) {63  StringRef N = Name;64  CPU = llvm::StringSwitch<CPUKind>(N)65            .Case("generic", CK_68000)66            .Case("M68000", CK_68000)67            .Case("M68010", CK_68010)68            .Case("M68020", CK_68020)69            .Case("M68030", CK_68030)70            .Case("M68040", CK_68040)71            .Case("M68060", CK_68060)72            .Default(CK_Unknown);73  return CPU != CK_Unknown;74}75 76void M68kTargetInfo::getTargetDefines(const LangOptions &Opts,77                                      MacroBuilder &Builder) const {78  using llvm::Twine;79 80  Builder.defineMacro("__m68k__");81 82  DefineStd(Builder, "mc68000", Opts);83 84  // For sub-architecture85  switch (CPU) {86  case CK_68010:87    DefineStd(Builder, "mc68010", Opts);88    break;89  case CK_68020:90    DefineStd(Builder, "mc68020", Opts);91    break;92  case CK_68030:93    DefineStd(Builder, "mc68030", Opts);94    break;95  case CK_68040:96    DefineStd(Builder, "mc68040", Opts);97    break;98  case CK_68060:99    DefineStd(Builder, "mc68060", Opts);100    break;101  default:102    break;103  }104 105  if (CPU >= CK_68020) {106    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");107    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");108    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");109  }110 111  // Floating point112  if (TargetOpts.FeatureMap.lookup("isa-68881") ||113      TargetOpts.FeatureMap.lookup("isa-68882"))114    Builder.defineMacro("__HAVE_68881__");115}116 117llvm::SmallVector<Builtin::InfosShard>118M68kTargetInfo::getTargetBuiltins() const {119  // FIXME: Implement.120  return {};121}122 123bool M68kTargetInfo::hasFeature(StringRef Feature) const {124  // FIXME elaborate moar125  return Feature == "M68000";126}127 128const char *const M68kTargetInfo::GCCRegNames[] = {129    "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",130    "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp",131    "pc"};132 133ArrayRef<const char *> M68kTargetInfo::getGCCRegNames() const {134  return llvm::ArrayRef(GCCRegNames);135}136 137const TargetInfo::GCCRegAlias M68kTargetInfo::GCCRegAliases[] = {138    {{"bp"}, "a5"},139    {{"fp"}, "a6"},140    {{"usp", "ssp", "isp", "a7"}, "sp"},141};142 143ArrayRef<TargetInfo::GCCRegAlias> M68kTargetInfo::getGCCRegAliases() const {144  return llvm::ArrayRef(GCCRegAliases);145}146 147bool M68kTargetInfo::validateAsmConstraint(148    const char *&Name, TargetInfo::ConstraintInfo &info) const {149  switch (*Name) {150  case 'a': // address register151  case 'd': // data register152    info.setAllowsRegister();153    return true;154  case 'I': // constant integer in the range [1,8]155    info.setRequiresImmediate(1, 8);156    return true;157  case 'J': // constant signed 16-bit integer158    info.setRequiresImmediate(std::numeric_limits<int16_t>::min(),159                              std::numeric_limits<int16_t>::max());160    return true;161  case 'K': // constant that is NOT in the range of [-0x80, 0x80)162    info.setRequiresImmediate();163    return true;164  case 'L': // constant integer in the range [-8,-1]165    info.setRequiresImmediate(-8, -1);166    return true;167  case 'M': // constant that is NOT in the range of [-0x100, 0x100]168    info.setRequiresImmediate();169    return true;170  case 'N': // constant integer in the range [24,31]171    info.setRequiresImmediate(24, 31);172    return true;173  case 'O': // constant integer 16174    info.setRequiresImmediate(16);175    return true;176  case 'P': // constant integer in the range [8,15]177    info.setRequiresImmediate(8, 15);178    return true;179  case 'C':180    ++Name;181    switch (*Name) {182    case '0': // constant integer 0183      info.setRequiresImmediate(0);184      return true;185    case 'i': // constant integer186    case 'j': // integer constant that doesn't fit in 16 bits187      info.setRequiresImmediate();188      return true;189    default:190      break;191    }192    break;193  case 'Q': // address register indirect addressing194  case 'U': // address register indirect w/ constant offset addressing195    // TODO: Handle 'S' (basically 'm' when pc-rel is enforced) when196    // '-mpcrel' flag is properly handled by the driver.197    info.setAllowsMemory();198    return true;199  default:200    break;201  }202  return false;203}204 205std::optional<std::string>206M68kTargetInfo::handleAsmEscapedChar(char EscChar) const {207  char C;208  switch (EscChar) {209  case '.':210  case '#':211    C = EscChar;212    break;213  case '/':214    C = '%';215    break;216  case '$':217    C = 's';218    break;219  case '&':220    C = 'd';221    break;222  default:223    return std::nullopt;224  }225 226  return std::string(1, C);227}228 229std::string M68kTargetInfo::convertConstraint(const char *&Constraint) const {230  if (*Constraint == 'C')231    // Two-character constraint; add "^" hint for later parsing232    return std::string("^") + std::string(Constraint++, 2);233 234  return std::string(1, *Constraint);235}236 237std::string_view M68kTargetInfo::getClobbers() const {238  // FIXME: Is this really right?239  return "";240}241 242TargetInfo::BuiltinVaListKind M68kTargetInfo::getBuiltinVaListKind() const {243  return TargetInfo::VoidPtrBuiltinVaList;244}245 246TargetInfo::CallingConvCheckResult247M68kTargetInfo::checkCallingConvention(CallingConv CC) const {248  switch (CC) {249  case CC_C:250  case CC_M68kRTD:251    return CCCR_OK;252  default:253    return TargetInfo::checkCallingConvention(CC);254  }255}256} // namespace targets257} // namespace clang258