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/Host.h" 18 #include "llvm/Support/Regex.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 void m68k::getM68kTargetFeatures(const Driver &D, const llvm::Triple &Triple, 69 const ArgList &Args, 70 std::vector<StringRef> &Features) { 71 72 m68k::FloatABI FloatABI = m68k::getM68kFloatABI(D, Args); 73 if (FloatABI == m68k::FloatABI::Soft) 74 Features.push_back("-hard-float"); 75 76 // Handle '-ffixed-<register>' flags 77 if (Args.hasArg(options::OPT_ffixed_a0)) 78 Features.push_back("+reserve-a0"); 79 if (Args.hasArg(options::OPT_ffixed_a1)) 80 Features.push_back("+reserve-a1"); 81 if (Args.hasArg(options::OPT_ffixed_a2)) 82 Features.push_back("+reserve-a2"); 83 if (Args.hasArg(options::OPT_ffixed_a3)) 84 Features.push_back("+reserve-a3"); 85 if (Args.hasArg(options::OPT_ffixed_a4)) 86 Features.push_back("+reserve-a4"); 87 if (Args.hasArg(options::OPT_ffixed_a5)) 88 Features.push_back("+reserve-a5"); 89 if (Args.hasArg(options::OPT_ffixed_a6)) 90 Features.push_back("+reserve-a6"); 91 if (Args.hasArg(options::OPT_ffixed_d0)) 92 Features.push_back("+reserve-d0"); 93 if (Args.hasArg(options::OPT_ffixed_d1)) 94 Features.push_back("+reserve-d1"); 95 if (Args.hasArg(options::OPT_ffixed_d2)) 96 Features.push_back("+reserve-d2"); 97 if (Args.hasArg(options::OPT_ffixed_d3)) 98 Features.push_back("+reserve-d3"); 99 if (Args.hasArg(options::OPT_ffixed_d4)) 100 Features.push_back("+reserve-d4"); 101 if (Args.hasArg(options::OPT_ffixed_d5)) 102 Features.push_back("+reserve-d5"); 103 if (Args.hasArg(options::OPT_ffixed_d6)) 104 Features.push_back("+reserve-d6"); 105 if (Args.hasArg(options::OPT_ffixed_d7)) 106 Features.push_back("+reserve-d7"); 107 } 108 109 m68k::FloatABI m68k::getM68kFloatABI(const Driver &D, const ArgList &Args) { 110 m68k::FloatABI ABI = m68k::FloatABI::Invalid; 111 if (Arg *A = 112 Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float)) { 113 114 if (A->getOption().matches(options::OPT_msoft_float)) 115 ABI = m68k::FloatABI::Soft; 116 else if (A->getOption().matches(options::OPT_mhard_float)) 117 ABI = m68k::FloatABI::Hard; 118 } 119 120 // If unspecified, choose the default based on the platform. 121 if (ABI == m68k::FloatABI::Invalid) 122 ABI = m68k::FloatABI::Hard; 123 124 return ABI; 125 } 126