Path: blob/main/contrib/llvm-project/clang/lib/Basic/Targets/Mips.cpp
35266 views
//===--- Mips.cpp - Implement Mips target feature support -----------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements Mips TargetInfo objects.9//10//===----------------------------------------------------------------------===//1112#include "Mips.h"13#include "Targets.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"1819using namespace clang;20using namespace clang::targets;2122static constexpr Builtin::Info BuiltinInfo[] = {23#define BUILTIN(ID, TYPE, ATTRS) \24{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},25#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \26{#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},27#include "clang/Basic/BuiltinsMips.def"28};2930bool MipsTargetInfo::processorSupportsGPR64() const {31return llvm::StringSwitch<bool>(CPU)32.Case("mips3", true)33.Case("mips4", true)34.Case("mips5", true)35.Case("mips64", true)36.Case("mips64r2", true)37.Case("mips64r3", true)38.Case("mips64r5", true)39.Case("mips64r6", true)40.Case("octeon", true)41.Case("octeon+", true)42.Default(false);43}4445static constexpr llvm::StringLiteral ValidCPUNames[] = {46{"mips1"}, {"mips2"}, {"mips3"}, {"mips4"}, {"mips5"},47{"mips32"}, {"mips32r2"}, {"mips32r3"}, {"mips32r5"}, {"mips32r6"},48{"mips64"}, {"mips64r2"}, {"mips64r3"}, {"mips64r5"}, {"mips64r6"},49{"octeon"}, {"octeon+"}, {"p5600"}};5051bool MipsTargetInfo::isValidCPUName(StringRef Name) const {52return llvm::is_contained(ValidCPUNames, Name);53}5455void MipsTargetInfo::fillValidCPUList(56SmallVectorImpl<StringRef> &Values) const {57Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));58}5960unsigned MipsTargetInfo::getISARev() const {61return llvm::StringSwitch<unsigned>(getCPU())62.Cases("mips32", "mips64", 1)63.Cases("mips32r2", "mips64r2", "octeon", "octeon+", 2)64.Cases("mips32r3", "mips64r3", 3)65.Cases("mips32r5", "mips64r5", 5)66.Cases("mips32r6", "mips64r6", 6)67.Default(0);68}6970void MipsTargetInfo::getTargetDefines(const LangOptions &Opts,71MacroBuilder &Builder) const {72if (BigEndian) {73DefineStd(Builder, "MIPSEB", Opts);74Builder.defineMacro("_MIPSEB");75} else {76DefineStd(Builder, "MIPSEL", Opts);77Builder.defineMacro("_MIPSEL");78}7980Builder.defineMacro("__mips__");81Builder.defineMacro("_mips");82if (Opts.GNUMode)83Builder.defineMacro("mips");8485if (ABI == "o32") {86Builder.defineMacro("__mips", "32");87Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS32");88} else {89Builder.defineMacro("__mips", "64");90Builder.defineMacro("__mips64");91Builder.defineMacro("__mips64__");92Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS64");93}9495const std::string ISARev = std::to_string(getISARev());9697if (!ISARev.empty())98Builder.defineMacro("__mips_isa_rev", ISARev);99100if (ABI == "o32") {101Builder.defineMacro("__mips_o32");102Builder.defineMacro("_ABIO32", "1");103Builder.defineMacro("_MIPS_SIM", "_ABIO32");104} else if (ABI == "n32") {105Builder.defineMacro("__mips_n32");106Builder.defineMacro("_ABIN32", "2");107Builder.defineMacro("_MIPS_SIM", "_ABIN32");108} else if (ABI == "n64") {109Builder.defineMacro("__mips_n64");110Builder.defineMacro("_ABI64", "3");111Builder.defineMacro("_MIPS_SIM", "_ABI64");112} else113llvm_unreachable("Invalid ABI.");114115if (!IsNoABICalls) {116Builder.defineMacro("__mips_abicalls");117if (CanUseBSDABICalls)118Builder.defineMacro("__ABICALLS__");119}120121Builder.defineMacro("__REGISTER_PREFIX__", "");122123switch (FloatABI) {124case HardFloat:125Builder.defineMacro("__mips_hard_float", Twine(1));126break;127case SoftFloat:128Builder.defineMacro("__mips_soft_float", Twine(1));129break;130}131132if (IsSingleFloat)133Builder.defineMacro("__mips_single_float", Twine(1));134135switch (FPMode) {136case FPXX:137Builder.defineMacro("__mips_fpr", Twine(0));138break;139case FP32:140Builder.defineMacro("__mips_fpr", Twine(32));141break;142case FP64:143Builder.defineMacro("__mips_fpr", Twine(64));144break;145}146147if (FPMode == FP64 || IsSingleFloat)148Builder.defineMacro("_MIPS_FPSET", Twine(32));149else150Builder.defineMacro("_MIPS_FPSET", Twine(16));151if (NoOddSpreg)152Builder.defineMacro("_MIPS_SPFPSET", Twine(16));153else154Builder.defineMacro("_MIPS_SPFPSET", Twine(32));155156if (IsMips16)157Builder.defineMacro("__mips16", Twine(1));158159if (IsMicromips)160Builder.defineMacro("__mips_micromips", Twine(1));161162if (IsNan2008)163Builder.defineMacro("__mips_nan2008", Twine(1));164165if (IsAbs2008)166Builder.defineMacro("__mips_abs2008", Twine(1));167168switch (DspRev) {169default:170break;171case DSP1:172Builder.defineMacro("__mips_dsp_rev", Twine(1));173Builder.defineMacro("__mips_dsp", Twine(1));174break;175case DSP2:176Builder.defineMacro("__mips_dsp_rev", Twine(2));177Builder.defineMacro("__mips_dspr2", Twine(1));178Builder.defineMacro("__mips_dsp", Twine(1));179break;180}181182if (HasMSA)183Builder.defineMacro("__mips_msa", Twine(1));184185if (DisableMadd4)186Builder.defineMacro("__mips_no_madd4", Twine(1));187188Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(LangAS::Default)));189Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth()));190Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth()));191192Builder.defineMacro("_MIPS_ARCH", "\"" + CPU + "\"");193if (CPU == "octeon+")194Builder.defineMacro("_MIPS_ARCH_OCTEONP");195else196Builder.defineMacro("_MIPS_ARCH_" + StringRef(CPU).upper());197198if (StringRef(CPU).starts_with("octeon"))199Builder.defineMacro("__OCTEON__");200201if (CPU != "mips1") {202Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");203Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");204Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");205}206207// 32-bit MIPS processors don't have the necessary lld/scd instructions208// found in 64-bit processors. In the case of O32 on a 64-bit processor,209// the instructions exist but using them violates the ABI since they210// require 64-bit GPRs and O32 only supports 32-bit GPRs.211if (ABI == "n32" || ABI == "n64")212Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");213}214215bool MipsTargetInfo::hasFeature(StringRef Feature) const {216return llvm::StringSwitch<bool>(Feature)217.Case("mips", true)218.Case("dsp", DspRev >= DSP1)219.Case("dspr2", DspRev >= DSP2)220.Case("fp64", FPMode == FP64)221.Case("msa", HasMSA)222.Default(false);223}224225ArrayRef<Builtin::Info> MipsTargetInfo::getTargetBuiltins() const {226return llvm::ArrayRef(BuiltinInfo,227clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin);228}229230unsigned MipsTargetInfo::getUnwindWordWidth() const {231return llvm::StringSwitch<unsigned>(ABI)232.Case("o32", 32)233.Case("n32", 64)234.Case("n64", 64)235.Default(getPointerWidth(LangAS::Default));236}237238bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const {239// microMIPS64R6 backend was removed.240if (getTriple().isMIPS64() && IsMicromips && (ABI == "n32" || ABI == "n64")) {241Diags.Report(diag::err_target_unsupported_cpu_for_micromips) << CPU;242return false;243}244245// 64-bit ABI's require 64-bit CPU's.246if (!processorSupportsGPR64() && (ABI == "n32" || ABI == "n64")) {247Diags.Report(diag::err_target_unsupported_abi) << ABI << CPU;248return false;249}250251// -fpxx is valid only for the o32 ABI252if (FPMode == FPXX && (ABI == "n32" || ABI == "n64")) {253Diags.Report(diag::err_unsupported_abi_for_opt) << "-mfpxx" << "o32";254return false;255}256257// -mfp32 and n32/n64 ABIs are incompatible258if (FPMode != FP64 && FPMode != FPXX && !IsSingleFloat &&259(ABI == "n32" || ABI == "n64")) {260Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfpxx" << CPU;261return false;262}263// Mips revision 6 and -mfp32 are incompatible264if (FPMode != FP64 && FPMode != FPXX && (CPU == "mips32r6" ||265CPU == "mips64r6")) {266Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfp32" << CPU;267return false;268}269// Option -mfp64 permitted on Mips32 iff revision 2 or higher is present270if (FPMode == FP64 && (CPU == "mips1" || CPU == "mips2" ||271getISARev() < 2) && ABI == "o32") {272Diags.Report(diag::err_mips_fp64_req) << "-mfp64";273return false;274}275// FPXX requires mips2+276if (FPMode == FPXX && CPU == "mips1") {277Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfpxx" << CPU;278return false;279}280// -mmsa with -msoft-float makes nonsense281if (FloatABI == SoftFloat && HasMSA) {282Diags.Report(diag::err_opt_not_valid_with_opt) << "-msoft-float"283<< "-mmsa";284return false;285}286// Option -mmsa permitted on Mips32 iff revision 2 or higher is present287if (HasMSA && (CPU == "mips1" || CPU == "mips2" || getISARev() < 2) &&288ABI == "o32") {289Diags.Report(diag::err_mips_fp64_req) << "-mmsa";290return false;291}292// MSA requires FP64293if (FPMode == FPXX && HasMSA) {294Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfpxx"295<< "-mmsa";296return false;297}298if (FPMode == FP32 && HasMSA) {299Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfp32"300<< "-mmsa";301return false;302}303304return true;305}306307308