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 std::string m68k::getM68kTargetCPU(const ArgList &Args) { 28 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 StringRef CPUName = A->getValue(); 32 33 if (CPUName == "native") { 34 std::string CPU = std::string(llvm::sys::getHostCPUName()); 35 if (!CPU.empty() && CPU != "generic") 36 return CPU; 37 } 38 39 if (CPUName == "common") 40 return "generic"; 41 42 return llvm::StringSwitch<std::string>(CPUName) 43 .Cases("m68000", "68000", "M68000") 44 .Cases("m68010", "68010", "M68010") 45 .Cases("m68020", "68020", "M68020") 46 .Cases("m68030", "68030", "M68030") 47 .Cases("m68040", "68040", "M68040") 48 .Cases("m68060", "68060", "M68060") 49 .Default(CPUName.str()); 50 } 51 // FIXME: Throw error when multiple sub-architecture flag exist 52 if (Args.hasArg(clang::driver::options::OPT_m68000)) 53 return "M68000"; 54 if (Args.hasArg(clang::driver::options::OPT_m68010)) 55 return "M68010"; 56 if (Args.hasArg(clang::driver::options::OPT_m68020)) 57 return "M68020"; 58 if (Args.hasArg(clang::driver::options::OPT_m68030)) 59 return "M68030"; 60 if (Args.hasArg(clang::driver::options::OPT_m68040)) 61 return "M68040"; 62 if (Args.hasArg(clang::driver::options::OPT_m68060)) 63 return "M68060"; 64 65 return ""; 66 } 67 68 static void addFloatABIFeatures(const llvm::opt::ArgList &Args, 69 std::vector<llvm::StringRef> &Features) { 70 Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float, 71 options::OPT_m68881); 72 // Opt out FPU even for newer CPUs. 73 if (A && A->getOption().matches(options::OPT_msoft_float)) { 74 Features.push_back("-isa-68881"); 75 Features.push_back("-isa-68882"); 76 return; 77 } 78 79 std::string CPU = m68k::getM68kTargetCPU(Args); 80 // Only enable M68881 for CPU < 68020 if the related flags are present. 81 if ((A && (CPU == "M68000" || CPU == "M68010")) || 82 // Otherwise, by default we assume newer CPUs have M68881/2. 83 CPU == "M68020") 84 Features.push_back("+isa-68881"); 85 else if (CPU == "M68030" || CPU == "M68040" || CPU == "M68060") 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 Features.push_back("+isa-68882"); 91 } 92 93 void m68k::getM68kTargetFeatures(const Driver &D, const llvm::Triple &Triple, 94 const ArgList &Args, 95 std::vector<StringRef> &Features) { 96 addFloatABIFeatures(Args, Features); 97 98 // Handle '-ffixed-<register>' flags 99 if (Args.hasArg(options::OPT_ffixed_a0)) 100 Features.push_back("+reserve-a0"); 101 if (Args.hasArg(options::OPT_ffixed_a1)) 102 Features.push_back("+reserve-a1"); 103 if (Args.hasArg(options::OPT_ffixed_a2)) 104 Features.push_back("+reserve-a2"); 105 if (Args.hasArg(options::OPT_ffixed_a3)) 106 Features.push_back("+reserve-a3"); 107 if (Args.hasArg(options::OPT_ffixed_a4)) 108 Features.push_back("+reserve-a4"); 109 if (Args.hasArg(options::OPT_ffixed_a5)) 110 Features.push_back("+reserve-a5"); 111 if (Args.hasArg(options::OPT_ffixed_a6)) 112 Features.push_back("+reserve-a6"); 113 if (Args.hasArg(options::OPT_ffixed_d0)) 114 Features.push_back("+reserve-d0"); 115 if (Args.hasArg(options::OPT_ffixed_d1)) 116 Features.push_back("+reserve-d1"); 117 if (Args.hasArg(options::OPT_ffixed_d2)) 118 Features.push_back("+reserve-d2"); 119 if (Args.hasArg(options::OPT_ffixed_d3)) 120 Features.push_back("+reserve-d3"); 121 if (Args.hasArg(options::OPT_ffixed_d4)) 122 Features.push_back("+reserve-d4"); 123 if (Args.hasArg(options::OPT_ffixed_d5)) 124 Features.push_back("+reserve-d5"); 125 if (Args.hasArg(options::OPT_ffixed_d6)) 126 Features.push_back("+reserve-d6"); 127 if (Args.hasArg(options::OPT_ffixed_d7)) 128 Features.push_back("+reserve-d7"); 129 } 130