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