1*fe6060f1SDimitry Andric //===--- M68k.cpp - M68k Helpers for Tools -------------------*- C++-*-===// 2*fe6060f1SDimitry Andric // 3*fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*fe6060f1SDimitry Andric // 7*fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 8*fe6060f1SDimitry Andric 9*fe6060f1SDimitry Andric #include "M68k.h" 10*fe6060f1SDimitry Andric #include "ToolChains/CommonArgs.h" 11*fe6060f1SDimitry Andric #include "clang/Driver/Driver.h" 12*fe6060f1SDimitry Andric #include "clang/Driver/DriverDiagnostic.h" 13*fe6060f1SDimitry Andric #include "clang/Driver/Options.h" 14*fe6060f1SDimitry Andric #include "llvm/ADT/SmallVector.h" 15*fe6060f1SDimitry Andric #include "llvm/ADT/StringSwitch.h" 16*fe6060f1SDimitry Andric #include "llvm/Option/ArgList.h" 17*fe6060f1SDimitry Andric #include "llvm/Support/Host.h" 18*fe6060f1SDimitry Andric #include "llvm/Support/Regex.h" 19*fe6060f1SDimitry Andric #include <sstream> 20*fe6060f1SDimitry Andric 21*fe6060f1SDimitry Andric using namespace clang::driver; 22*fe6060f1SDimitry Andric using namespace clang::driver::tools; 23*fe6060f1SDimitry Andric using namespace clang; 24*fe6060f1SDimitry Andric using namespace llvm::opt; 25*fe6060f1SDimitry Andric 26*fe6060f1SDimitry Andric /// getM68kTargetCPU - Get the (LLVM) name of the 68000 cpu we are targeting. 27*fe6060f1SDimitry Andric std::string m68k::getM68kTargetCPU(const ArgList &Args) { 28*fe6060f1SDimitry Andric if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ)) { 29*fe6060f1SDimitry Andric // The canonical CPU name is captalize. However, we allow 30*fe6060f1SDimitry Andric // starting with lower case or numbers only 31*fe6060f1SDimitry Andric StringRef CPUName = A->getValue(); 32*fe6060f1SDimitry Andric 33*fe6060f1SDimitry Andric if (CPUName == "native") { 34*fe6060f1SDimitry Andric std::string CPU = std::string(llvm::sys::getHostCPUName()); 35*fe6060f1SDimitry Andric if (!CPU.empty() && CPU != "generic") 36*fe6060f1SDimitry Andric return CPU; 37*fe6060f1SDimitry Andric } 38*fe6060f1SDimitry Andric 39*fe6060f1SDimitry Andric if (CPUName == "common") 40*fe6060f1SDimitry Andric return "generic"; 41*fe6060f1SDimitry Andric 42*fe6060f1SDimitry Andric return llvm::StringSwitch<std::string>(CPUName) 43*fe6060f1SDimitry Andric .Cases("m68000", "68000", "M68000") 44*fe6060f1SDimitry Andric .Cases("m68010", "68010", "M68010") 45*fe6060f1SDimitry Andric .Cases("m68020", "68020", "M68020") 46*fe6060f1SDimitry Andric .Cases("m68030", "68030", "M68030") 47*fe6060f1SDimitry Andric .Cases("m68040", "68040", "M68040") 48*fe6060f1SDimitry Andric .Cases("m68060", "68060", "M68060") 49*fe6060f1SDimitry Andric .Default(CPUName.str()); 50*fe6060f1SDimitry Andric } 51*fe6060f1SDimitry Andric // FIXME: Throw error when multiple sub-architecture flag exist 52*fe6060f1SDimitry Andric if (Args.hasArg(clang::driver::options::OPT_m68000)) 53*fe6060f1SDimitry Andric return "M68000"; 54*fe6060f1SDimitry Andric if (Args.hasArg(clang::driver::options::OPT_m68010)) 55*fe6060f1SDimitry Andric return "M68010"; 56*fe6060f1SDimitry Andric if (Args.hasArg(clang::driver::options::OPT_m68020)) 57*fe6060f1SDimitry Andric return "M68020"; 58*fe6060f1SDimitry Andric if (Args.hasArg(clang::driver::options::OPT_m68030)) 59*fe6060f1SDimitry Andric return "M68030"; 60*fe6060f1SDimitry Andric if (Args.hasArg(clang::driver::options::OPT_m68040)) 61*fe6060f1SDimitry Andric return "M68040"; 62*fe6060f1SDimitry Andric if (Args.hasArg(clang::driver::options::OPT_m68060)) 63*fe6060f1SDimitry Andric return "M68060"; 64*fe6060f1SDimitry Andric 65*fe6060f1SDimitry Andric return ""; 66*fe6060f1SDimitry Andric } 67*fe6060f1SDimitry Andric 68*fe6060f1SDimitry Andric void m68k::getM68kTargetFeatures(const Driver &D, const llvm::Triple &Triple, 69*fe6060f1SDimitry Andric const ArgList &Args, 70*fe6060f1SDimitry Andric std::vector<StringRef> &Features) { 71*fe6060f1SDimitry Andric 72*fe6060f1SDimitry Andric m68k::FloatABI FloatABI = m68k::getM68kFloatABI(D, Args); 73*fe6060f1SDimitry Andric if (FloatABI == m68k::FloatABI::Soft) 74*fe6060f1SDimitry Andric Features.push_back("-hard-float"); 75*fe6060f1SDimitry Andric 76*fe6060f1SDimitry Andric // Handle '-ffixed-<register>' flags 77*fe6060f1SDimitry Andric if (Args.hasArg(options::OPT_ffixed_a0)) 78*fe6060f1SDimitry Andric Features.push_back("+reserve-a0"); 79*fe6060f1SDimitry Andric if (Args.hasArg(options::OPT_ffixed_a1)) 80*fe6060f1SDimitry Andric Features.push_back("+reserve-a1"); 81*fe6060f1SDimitry Andric if (Args.hasArg(options::OPT_ffixed_a2)) 82*fe6060f1SDimitry Andric Features.push_back("+reserve-a2"); 83*fe6060f1SDimitry Andric if (Args.hasArg(options::OPT_ffixed_a3)) 84*fe6060f1SDimitry Andric Features.push_back("+reserve-a3"); 85*fe6060f1SDimitry Andric if (Args.hasArg(options::OPT_ffixed_a4)) 86*fe6060f1SDimitry Andric Features.push_back("+reserve-a4"); 87*fe6060f1SDimitry Andric if (Args.hasArg(options::OPT_ffixed_a5)) 88*fe6060f1SDimitry Andric Features.push_back("+reserve-a5"); 89*fe6060f1SDimitry Andric if (Args.hasArg(options::OPT_ffixed_a6)) 90*fe6060f1SDimitry Andric Features.push_back("+reserve-a6"); 91*fe6060f1SDimitry Andric if (Args.hasArg(options::OPT_ffixed_d0)) 92*fe6060f1SDimitry Andric Features.push_back("+reserve-d0"); 93*fe6060f1SDimitry Andric if (Args.hasArg(options::OPT_ffixed_d1)) 94*fe6060f1SDimitry Andric Features.push_back("+reserve-d1"); 95*fe6060f1SDimitry Andric if (Args.hasArg(options::OPT_ffixed_d2)) 96*fe6060f1SDimitry Andric Features.push_back("+reserve-d2"); 97*fe6060f1SDimitry Andric if (Args.hasArg(options::OPT_ffixed_d3)) 98*fe6060f1SDimitry Andric Features.push_back("+reserve-d3"); 99*fe6060f1SDimitry Andric if (Args.hasArg(options::OPT_ffixed_d4)) 100*fe6060f1SDimitry Andric Features.push_back("+reserve-d4"); 101*fe6060f1SDimitry Andric if (Args.hasArg(options::OPT_ffixed_d5)) 102*fe6060f1SDimitry Andric Features.push_back("+reserve-d5"); 103*fe6060f1SDimitry Andric if (Args.hasArg(options::OPT_ffixed_d6)) 104*fe6060f1SDimitry Andric Features.push_back("+reserve-d6"); 105*fe6060f1SDimitry Andric if (Args.hasArg(options::OPT_ffixed_d7)) 106*fe6060f1SDimitry Andric Features.push_back("+reserve-d7"); 107*fe6060f1SDimitry Andric } 108*fe6060f1SDimitry Andric 109*fe6060f1SDimitry Andric m68k::FloatABI m68k::getM68kFloatABI(const Driver &D, const ArgList &Args) { 110*fe6060f1SDimitry Andric m68k::FloatABI ABI = m68k::FloatABI::Invalid; 111*fe6060f1SDimitry Andric if (Arg *A = 112*fe6060f1SDimitry Andric Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float)) { 113*fe6060f1SDimitry Andric 114*fe6060f1SDimitry Andric if (A->getOption().matches(options::OPT_msoft_float)) 115*fe6060f1SDimitry Andric ABI = m68k::FloatABI::Soft; 116*fe6060f1SDimitry Andric else if (A->getOption().matches(options::OPT_mhard_float)) 117*fe6060f1SDimitry Andric ABI = m68k::FloatABI::Hard; 118*fe6060f1SDimitry Andric } 119*fe6060f1SDimitry Andric 120*fe6060f1SDimitry Andric // If unspecified, choose the default based on the platform. 121*fe6060f1SDimitry Andric if (ABI == m68k::FloatABI::Invalid) 122*fe6060f1SDimitry Andric ABI = m68k::FloatABI::Hard; 123*fe6060f1SDimitry Andric 124*fe6060f1SDimitry Andric return ABI; 125*fe6060f1SDimitry Andric } 126