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