brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.7 KiB · a999d14 Raw
375 lines · cpp
1//===--- Mips.cpp - Implement Mips 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 Mips TargetInfo objects.10//11//===----------------------------------------------------------------------===//12 13#include "Mips.h"14#include "clang/Basic/Diagnostic.h"15#include "clang/Basic/MacroBuilder.h"16#include "clang/Basic/TargetBuiltins.h"17#include "llvm/ADT/StringSwitch.h"18 19using namespace clang;20using namespace clang::targets;21 22static constexpr int NumBuiltins =23    clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin;24 25static constexpr llvm::StringTable BuiltinStrings =26    CLANG_BUILTIN_STR_TABLE_START27#define BUILTIN CLANG_BUILTIN_STR_TABLE28#include "clang/Basic/BuiltinsMips.def"29    ;30 31static constexpr auto BuiltinInfos = Builtin::MakeInfos<NumBuiltins>({32#define BUILTIN CLANG_BUILTIN_ENTRY33#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY34#include "clang/Basic/BuiltinsMips.def"35});36 37bool MipsTargetInfo::processorSupportsGPR64() const {38  return llvm::StringSwitch<bool>(CPU)39      .Case("mips3", true)40      .Case("mips4", true)41      .Case("mips5", true)42      .Case("mips64", true)43      .Case("mips64r2", true)44      .Case("mips64r3", true)45      .Case("mips64r5", true)46      .Case("mips64r6", true)47      .Case("octeon", true)48      .Case("octeon+", true)49      .Case("i6400", true)50      .Case("i6500", true)51      .Default(false);52}53 54static constexpr llvm::StringLiteral ValidCPUNames[] = {55    {"mips1"},  {"mips2"},    {"mips3"},    {"mips4"},    {"mips5"},56    {"mips32"}, {"mips32r2"}, {"mips32r3"}, {"mips32r5"}, {"mips32r6"},57    {"mips64"}, {"mips64r2"}, {"mips64r3"}, {"mips64r5"}, {"mips64r6"},58    {"octeon"}, {"octeon+"},  {"p5600"},    {"i6400"},    {"i6500"}};59 60bool MipsTargetInfo::isValidCPUName(StringRef Name) const {61  return llvm::is_contained(ValidCPUNames, Name);62}63 64void MipsTargetInfo::fillValidCPUList(65    SmallVectorImpl<StringRef> &Values) const {66  Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));67}68 69unsigned MipsTargetInfo::getISARev() const {70  return llvm::StringSwitch<unsigned>(getCPU())71      .Cases({"mips32", "mips64"}, 1)72      .Cases({"mips32r2", "mips64r2", "octeon", "octeon+"}, 2)73      .Cases({"mips32r3", "mips64r3"}, 3)74      .Cases({"mips32r5", "mips64r5", "p5600"}, 5)75      .Cases({"mips32r6", "mips64r6", "i6400", "i6500"}, 6)76      .Default(0);77}78 79void MipsTargetInfo::getTargetDefines(const LangOptions &Opts,80                                      MacroBuilder &Builder) const {81  if (BigEndian) {82    DefineStd(Builder, "MIPSEB", Opts);83    Builder.defineMacro("_MIPSEB");84  } else {85    DefineStd(Builder, "MIPSEL", Opts);86    Builder.defineMacro("_MIPSEL");87  }88 89  Builder.defineMacro("__mips__");90  Builder.defineMacro("_mips");91  if (Opts.GNUMode)92    Builder.defineMacro("mips");93 94  if (ABI == "o32") {95    Builder.defineMacro("__mips", "32");96    Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS32");97  } else {98    Builder.defineMacro("__mips", "64");99    Builder.defineMacro("__mips64");100    Builder.defineMacro("__mips64__");101    Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS64");102  }103 104  const std::string ISARev = std::to_string(getISARev());105 106  if (!ISARev.empty())107    Builder.defineMacro("__mips_isa_rev", ISARev);108 109  if (ABI == "o32") {110    Builder.defineMacro("__mips_o32");111    Builder.defineMacro("_ABIO32", "1");112    Builder.defineMacro("_MIPS_SIM", "_ABIO32");113  } else if (ABI == "n32") {114    Builder.defineMacro("__mips_n32");115    Builder.defineMacro("_ABIN32", "2");116    Builder.defineMacro("_MIPS_SIM", "_ABIN32");117  } else if (ABI == "n64") {118    Builder.defineMacro("__mips_n64");119    Builder.defineMacro("_ABI64", "3");120    Builder.defineMacro("_MIPS_SIM", "_ABI64");121  } else122    llvm_unreachable("Invalid ABI.");123 124  if (!IsNoABICalls) {125    Builder.defineMacro("__mips_abicalls");126    if (CanUseBSDABICalls)127      Builder.defineMacro("__ABICALLS__");128  }129 130  Builder.defineMacro("__REGISTER_PREFIX__", "");131 132  switch (FloatABI) {133  case HardFloat:134    Builder.defineMacro("__mips_hard_float", Twine(1));135    break;136  case SoftFloat:137    Builder.defineMacro("__mips_soft_float", Twine(1));138    break;139  }140 141  if (IsSingleFloat)142    Builder.defineMacro("__mips_single_float", Twine(1));143 144  switch (FPMode) {145  case FPXX:146    Builder.defineMacro("__mips_fpr", Twine(0));147    break;148  case FP32:149    Builder.defineMacro("__mips_fpr", Twine(32));150    break;151  case FP64:152    Builder.defineMacro("__mips_fpr", Twine(64));153    break;154}155 156  if (FPMode == FP64 || IsSingleFloat)157    Builder.defineMacro("_MIPS_FPSET", Twine(32));158  else159    Builder.defineMacro("_MIPS_FPSET", Twine(16));160  if (NoOddSpreg)161    Builder.defineMacro("_MIPS_SPFPSET", Twine(16));162  else163    Builder.defineMacro("_MIPS_SPFPSET", Twine(32));164 165  if (IsMips16)166    Builder.defineMacro("__mips16", Twine(1));167 168  if (IsMicromips)169    Builder.defineMacro("__mips_micromips", Twine(1));170 171  if (IsNan2008)172    Builder.defineMacro("__mips_nan2008", Twine(1));173 174  if (IsAbs2008)175    Builder.defineMacro("__mips_abs2008", Twine(1));176 177  switch (DspRev) {178  default:179    break;180  case DSP1:181    Builder.defineMacro("__mips_dsp_rev", Twine(1));182    Builder.defineMacro("__mips_dsp", Twine(1));183    break;184  case DSP2:185    Builder.defineMacro("__mips_dsp_rev", Twine(2));186    Builder.defineMacro("__mips_dspr2", Twine(1));187    Builder.defineMacro("__mips_dsp", Twine(1));188    break;189  }190 191  if (HasMSA)192    Builder.defineMacro("__mips_msa", Twine(1));193 194  if (DisableMadd4)195    Builder.defineMacro("__mips_no_madd4", Twine(1));196 197  Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(LangAS::Default)));198  Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth()));199  Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth()));200 201  Builder.defineMacro("_MIPS_ARCH", "\"" + CPU + "\"");202  if (CPU == "octeon+")203    Builder.defineMacro("_MIPS_ARCH_OCTEONP");204  else205    Builder.defineMacro("_MIPS_ARCH_" + StringRef(CPU).upper());206 207  if (StringRef(CPU).starts_with("octeon"))208    Builder.defineMacro("__OCTEON__");209 210  if (CPU != "mips1") {211    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");212    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");213    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");214  }215 216  // 32-bit MIPS processors don't have the necessary lld/scd instructions217  // found in 64-bit processors. In the case of O32 on a 64-bit processor,218  // the instructions exist but using them violates the ABI since they219  // require 64-bit GPRs and O32 only supports 32-bit GPRs.220  if (ABI == "n32" || ABI == "n64")221    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");222}223 224bool MipsTargetInfo::hasFeature(StringRef Feature) const {225  return llvm::StringSwitch<bool>(Feature)226      .Case("mips", true)227      .Case("dsp", DspRev >= DSP1)228      .Case("dspr2", DspRev >= DSP2)229      .Case("fp64", FPMode == FP64)230      .Case("msa", HasMSA)231      .Default(false);232}233 234llvm::SmallVector<Builtin::InfosShard>235MipsTargetInfo::getTargetBuiltins() const {236  return {{&BuiltinStrings, BuiltinInfos}};237}238 239unsigned MipsTargetInfo::getUnwindWordWidth() const {240  return llvm::StringSwitch<unsigned>(ABI)241      .Case("o32", 32)242      .Case("n32", 64)243      .Case("n64", 64)244      .Default(getPointerWidth(LangAS::Default));245}246 247bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const {248  // microMIPS64R6 backend was removed.249  if (getTriple().isMIPS64() && IsMicromips && (ABI == "n32" || ABI == "n64")) {250    Diags.Report(diag::err_target_unsupported_cpu_for_micromips) << CPU;251    return false;252  }253 254  // 64-bit ABI's require 64-bit CPU's.255  if (!processorSupportsGPR64() && (ABI == "n32" || ABI == "n64")) {256    Diags.Report(diag::err_target_unsupported_abi) << ABI << CPU;257    return false;258  }259 260  // -fpxx is valid only for the o32 ABI261  if (FPMode == FPXX && (ABI == "n32" || ABI == "n64")) {262    Diags.Report(diag::err_unsupported_abi_for_opt) << "-mfpxx" << "o32";263    return false;264  }265 266  // -mfp32 and n32/n64 ABIs are incompatible267  if (FPMode != FP64 && FPMode != FPXX && !IsSingleFloat &&268      (ABI == "n32" || ABI == "n64")) {269    Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfpxx" << CPU;270    return false;271  }272  // Mips revision 6 and -mfp32 are incompatible273  if (FPMode != FP64 && FPMode != FPXX &&274      (CPU == "mips32r6" || CPU == "mips64r6" || CPU == "i6400" ||275       CPU == "i6500")) {276    Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfp32" << CPU;277    return false;278  }279  // Option -mfp64 permitted on Mips32 iff revision 2 or higher is present280  if (FPMode == FP64 && (CPU == "mips1" || CPU == "mips2" ||281      getISARev() < 2) && ABI == "o32") {282    Diags.Report(diag::err_mips_fp64_req) << "-mfp64";283    return false;284  }285  // FPXX requires mips2+286  if (FPMode == FPXX && CPU == "mips1") {287    Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfpxx" << CPU;288    return false;289  }290  // -mmsa with -msoft-float makes nonsense291  if (FloatABI == SoftFloat && HasMSA) {292    Diags.Report(diag::err_opt_not_valid_with_opt) << "-msoft-float"293                                                   << "-mmsa";294    return false;295  }296  // Option -mmsa permitted on Mips32 iff revision 2 or higher is present297  if (HasMSA && (CPU == "mips1" || CPU == "mips2" || getISARev() < 2) &&298      ABI == "o32") {299    Diags.Report(diag::err_mips_fp64_req) << "-mmsa";300    return false;301  }302  // MSA requires FP64303  if (FPMode == FPXX && HasMSA) {304    Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfpxx"305                                                   << "-mmsa";306    return false;307  }308  if (FPMode == FP32 && HasMSA) {309    Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfp32"310                                                   << "-mmsa";311    return false;312  }313 314  return true;315}316 317WindowsMipsTargetInfo::WindowsMipsTargetInfo(const llvm::Triple &Triple,318                                             const TargetOptions &Opts)319    : WindowsTargetInfo<MipsTargetInfo>(Triple, Opts), Triple(Triple) {}320 321void WindowsMipsTargetInfo::getVisualStudioDefines(322    const LangOptions &Opts, MacroBuilder &Builder) const {323  Builder.defineMacro("_M_MRX000", "4000");324}325 326TargetInfo::BuiltinVaListKind327WindowsMipsTargetInfo::getBuiltinVaListKind() const {328  return TargetInfo::CharPtrBuiltinVaList;329}330 331TargetInfo::CallingConvCheckResult332WindowsMipsTargetInfo::checkCallingConvention(CallingConv CC) const {333  switch (CC) {334  case CC_X86StdCall:335  case CC_X86ThisCall:336  case CC_X86FastCall:337  case CC_X86VectorCall:338    return CCCR_Ignore;339  case CC_C:340  case CC_DeviceKernel:341  case CC_PreserveMost:342  case CC_PreserveAll:343  case CC_Swift:344  case CC_SwiftAsync:345    return CCCR_OK;346  default:347    return CCCR_Warning;348  }349}350 351// Windows MIPS, MS (C++) ABI352MicrosoftMipsTargetInfo::MicrosoftMipsTargetInfo(const llvm::Triple &Triple,353                                                 const TargetOptions &Opts)354    : WindowsMipsTargetInfo(Triple, Opts) {355  TheCXXABI.set(TargetCXXABI::Microsoft);356}357 358void MicrosoftMipsTargetInfo::getTargetDefines(const LangOptions &Opts,359                                               MacroBuilder &Builder) const {360  WindowsMipsTargetInfo::getTargetDefines(Opts, Builder);361  WindowsMipsTargetInfo::getVisualStudioDefines(Opts, Builder);362}363 364MinGWMipsTargetInfo::MinGWMipsTargetInfo(const llvm::Triple &Triple,365                                         const TargetOptions &Opts)366    : WindowsMipsTargetInfo(Triple, Opts) {367  TheCXXABI.set(TargetCXXABI::GenericMIPS);368}369 370void MinGWMipsTargetInfo::getTargetDefines(const LangOptions &Opts,371                                           MacroBuilder &Builder) const {372  WindowsMipsTargetInfo::getTargetDefines(Opts, Builder);373  Builder.defineMacro("_MIPS_");374}375