//===--- M68k.cpp - M68k Helpers for Tools -------------------*- C++-*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "M68k.h" #include "ToolChains/CommonArgs.h" #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Option/ArgList.h" #include "llvm/Support/Host.h" #include "llvm/Support/Regex.h" #include using namespace clang::driver; using namespace clang::driver::tools; using namespace clang; using namespace llvm::opt; /// getM68kTargetCPU - Get the (LLVM) name of the 68000 cpu we are targeting. std::string m68k::getM68kTargetCPU(const ArgList &Args) { if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ)) { // The canonical CPU name is captalize. However, we allow // starting with lower case or numbers only StringRef CPUName = A->getValue(); if (CPUName == "native") { std::string CPU = std::string(llvm::sys::getHostCPUName()); if (!CPU.empty() && CPU != "generic") return CPU; } if (CPUName == "common") return "generic"; return llvm::StringSwitch(CPUName) .Cases("m68000", "68000", "M68000") .Cases("m68010", "68010", "M68010") .Cases("m68020", "68020", "M68020") .Cases("m68030", "68030", "M68030") .Cases("m68040", "68040", "M68040") .Cases("m68060", "68060", "M68060") .Default(CPUName.str()); } // FIXME: Throw error when multiple sub-architecture flag exist if (Args.hasArg(clang::driver::options::OPT_m68000)) return "M68000"; if (Args.hasArg(clang::driver::options::OPT_m68010)) return "M68010"; if (Args.hasArg(clang::driver::options::OPT_m68020)) return "M68020"; if (Args.hasArg(clang::driver::options::OPT_m68030)) return "M68030"; if (Args.hasArg(clang::driver::options::OPT_m68040)) return "M68040"; if (Args.hasArg(clang::driver::options::OPT_m68060)) return "M68060"; return ""; } void m68k::getM68kTargetFeatures(const Driver &D, const llvm::Triple &Triple, const ArgList &Args, std::vector &Features) { m68k::FloatABI FloatABI = m68k::getM68kFloatABI(D, Args); if (FloatABI == m68k::FloatABI::Soft) Features.push_back("-hard-float"); // Handle '-ffixed-' flags if (Args.hasArg(options::OPT_ffixed_a0)) Features.push_back("+reserve-a0"); if (Args.hasArg(options::OPT_ffixed_a1)) Features.push_back("+reserve-a1"); if (Args.hasArg(options::OPT_ffixed_a2)) Features.push_back("+reserve-a2"); if (Args.hasArg(options::OPT_ffixed_a3)) Features.push_back("+reserve-a3"); if (Args.hasArg(options::OPT_ffixed_a4)) Features.push_back("+reserve-a4"); if (Args.hasArg(options::OPT_ffixed_a5)) Features.push_back("+reserve-a5"); if (Args.hasArg(options::OPT_ffixed_a6)) Features.push_back("+reserve-a6"); if (Args.hasArg(options::OPT_ffixed_d0)) Features.push_back("+reserve-d0"); if (Args.hasArg(options::OPT_ffixed_d1)) Features.push_back("+reserve-d1"); if (Args.hasArg(options::OPT_ffixed_d2)) Features.push_back("+reserve-d2"); if (Args.hasArg(options::OPT_ffixed_d3)) Features.push_back("+reserve-d3"); if (Args.hasArg(options::OPT_ffixed_d4)) Features.push_back("+reserve-d4"); if (Args.hasArg(options::OPT_ffixed_d5)) Features.push_back("+reserve-d5"); if (Args.hasArg(options::OPT_ffixed_d6)) Features.push_back("+reserve-d6"); if (Args.hasArg(options::OPT_ffixed_d7)) Features.push_back("+reserve-d7"); } m68k::FloatABI m68k::getM68kFloatABI(const Driver &D, const ArgList &Args) { m68k::FloatABI ABI = m68k::FloatABI::Invalid; if (Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float)) { if (A->getOption().matches(options::OPT_msoft_float)) ABI = m68k::FloatABI::Soft; else if (A->getOption().matches(options::OPT_mhard_float)) ABI = m68k::FloatABI::Hard; } // If unspecified, choose the default based on the platform. if (ABI == m68k::FloatABI::Invalid) ABI = m68k::FloatABI::Hard; return ABI; }