Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -151,6 +151,8 @@ Group, DocName<"Hexagon">; def m_mips_Features_Group : OptionGroup<"">, Group, DocName<"MIPS">; +def m_m680x0_Features_Group: OptionGroup<"">, + Group, DocName<"M680x0">; def m_ppc_Features_Group : OptionGroup<"">, Group, DocName<"PowerPC">; def m_wasm_Features_Group : OptionGroup<"">, @@ -3118,6 +3120,9 @@ def mno_nvs : Flag<["-"], "mno-nvs">, Group, Flags<[CC1Option]>, HelpText<"Disable generation of new-value stores">; +// M680x0 features flags +foreach i = {0-4} in + def m680#i#0 : Flag<["-"], "m680"#i#"0">, Group; // X86 feature flags def mx87 : Flag<["-"], "mx87">, Group; Index: clang/lib/Driver/CMakeLists.txt =================================================================== --- clang/lib/Driver/CMakeLists.txt +++ clang/lib/Driver/CMakeLists.txt @@ -26,6 +26,7 @@ ToolChain.cpp ToolChains/Arch/AArch64.cpp ToolChains/Arch/ARM.cpp + ToolChains/Arch/M680x0.cpp ToolChains/Arch/Mips.cpp ToolChains/Arch/PPC.cpp ToolChains/Arch/RISCV.cpp Index: clang/lib/Driver/ToolChains/Arch/M680x0.h =================================================================== --- /dev/null +++ clang/lib/Driver/ToolChains/Arch/M680x0.h @@ -0,0 +1,42 @@ +//===--- M680x0.h - M680x0-specific Tool Helpers -----------------*- C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_M680X0_H +#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_M680X0_H + +#include "clang/Driver/Driver.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Option/Option.h" +#include +#include + +namespace clang { +namespace driver { +namespace tools { +namespace m680x0 { + +enum class FloatABI { + Invalid, + Soft, + Hard, +}; + +FloatABI getM680x0FloatABI(const Driver &D, const llvm::opt::ArgList &Args); + +std::string getM680x0TargetCPU(const llvm::opt::ArgList &Args); + +void getM680x0TargetFeatures(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args, + std::vector &Features); + +} // end namespace m680x0 +} // namespace tools +} // end namespace driver +} // end namespace clang + +#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_M680X0_H Index: clang/lib/Driver/ToolChains/Arch/M680x0.cpp =================================================================== --- /dev/null +++ clang/lib/Driver/ToolChains/Arch/M680x0.cpp @@ -0,0 +1,97 @@ +//===--- M680x0.cpp - M680x0 Helpers for Tools -------------------*- C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "M680x0.h" +#include "ToolChains/CommonArgs.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/DriverDiagnostic.h" +#include "clang/Driver/Options.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Option/ArgList.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/Regex.h" +#include + +using namespace clang::driver; +using namespace clang::driver::tools; +using namespace clang; +using namespace llvm::opt; + +/// getM680x0TargetCPU - Get the (LLVM) name of the 68000 cpu we are targeting. +std::string m680x0::getM680x0TargetCPU(const ArgList &Args) { + if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ)) { + // The canonical CPU name is captalize. However, we allow + // starting with lower case or numbers only + StringRef CPUName = A->getValue(); + + if (CPUName == "native") { + std::string CPU = std::string(llvm::sys::getHostCPUName()); + if (!CPU.empty() && CPU != "generic") + return CPU; + else + return ""; + } + + if (CPUName == "common") + return "generic"; + + llvm::Regex CPUPattern("m?680([01234]{1})0"); + llvm::SmallVector Matches; + if (CPUPattern.match(CPUName, &Matches) && Matches.size() == 2U) { + std::stringstream SS; + SS << "M680" << Matches[1].str() << "0"; + return SS.str(); + } + return CPUName.str(); + } + // FIXME: Throw error when multiple sub-architecture flag exist + else if (Args.hasArg(clang::driver::options::OPT_m68000)) { + return "M68000"; + } else if (Args.hasArg(clang::driver::options::OPT_m68010)) { + return "M68010"; + } else if (Args.hasArg(clang::driver::options::OPT_m68020)) { + return "M68020"; + } else if (Args.hasArg(clang::driver::options::OPT_m68030)) { + return "M68030"; + } else if (Args.hasArg(clang::driver::options::OPT_m68040)) { + return "M68040"; + } + + return ""; +} + +void m680x0::getM680x0TargetFeatures(const Driver &D, + const llvm::Triple &Triple, + const ArgList &Args, + std::vector &Features) { + + m680x0::FloatABI FloatABI = m680x0::getM680x0FloatABI(D, Args); + if (FloatABI == m680x0::FloatABI::Soft) + Features.push_back("-hard-float"); +} + +m680x0::FloatABI m680x0::getM680x0FloatABI(const Driver &D, + const ArgList &Args) { + m680x0::FloatABI ABI = m680x0::FloatABI::Invalid; + if (Arg *A = + Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float)) { + + if (A->getOption().matches(options::OPT_msoft_float)) + ABI = m680x0::FloatABI::Soft; + else if (A->getOption().matches(options::OPT_mhard_float)) + ABI = m680x0::FloatABI::Hard; + } + + // If unspecified, choose the default based on the platform. + if (ABI == m680x0::FloatABI::Invalid) { + ABI = m680x0::FloatABI::Hard; + } + + return ABI; +} Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -10,6 +10,7 @@ #include "AMDGPU.h" #include "Arch/AArch64.h" #include "Arch/ARM.h" +#include "Arch/M680x0.h" #include "Arch/Mips.h" #include "Arch/PPC.h" #include "Arch/RISCV.h" @@ -373,6 +374,10 @@ break; case llvm::Triple::ve: ve::getVETargetFeatures(D, Args, Features); + break; + case llvm::Triple::m680x0: + m680x0::getM680x0TargetFeatures(D, Triple, Args, Features); + break; } for (auto Feature : unifyTargetFeatures(Features)) { Index: clang/lib/Driver/ToolChains/CommonArgs.cpp =================================================================== --- clang/lib/Driver/ToolChains/CommonArgs.cpp +++ clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -9,6 +9,7 @@ #include "CommonArgs.h" #include "Arch/AArch64.h" #include "Arch/ARM.h" +#include "Arch/M680x0.h" #include "Arch/Mips.h" #include "Arch/PPC.h" #include "Arch/SystemZ.h" @@ -292,6 +293,9 @@ return arm::getARMTargetCPU(MCPU, MArch, T); } + case llvm::Triple::m680x0: + return m680x0::getM680x0TargetCPU(Args); + case llvm::Triple::avr: if (const Arg *A = Args.getLastArg(options::OPT_mmcu_EQ)) return A->getValue(); Index: clang/lib/Driver/ToolChains/Gnu.cpp =================================================================== --- clang/lib/Driver/ToolChains/Gnu.cpp +++ clang/lib/Driver/ToolChains/Gnu.cpp @@ -252,6 +252,8 @@ case llvm::Triple::armeb: case llvm::Triple::thumbeb: return isArmBigEndian(T, Args) ? "armelfb_linux_eabi" : "armelf_linux_eabi"; + case llvm::Triple::m680x0: + return "m68kelf"; case llvm::Triple::ppc: return "elf32ppclinux"; case llvm::Triple::ppc64: @@ -2082,6 +2084,10 @@ "i686-linux-android", "i386-gnu", "i486-gnu", "i586-gnu", "i686-gnu"}; + static const char *const M680x0LibDirs[] = {"/lib"}; + static const char *const M680x0Triples[] = { + "m68k-linux-gnu", "m68k-unknown-linux-gnu", "m68k-suse-linux"}; + static const char *const MIPSLibDirs[] = {"/lib"}; static const char *const MIPSTriples[] = { "mips-linux-gnu", "mips-mti-linux", "mips-mti-linux-gnu", @@ -2315,6 +2321,10 @@ BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples)); } break; + case llvm::Triple::m680x0: + LibDirs.append(begin(M680x0LibDirs), end(M680x0LibDirs)); + TripleAliases.append(begin(M680x0Triples), end(M680x0Triples)); + break; case llvm::Triple::mips: LibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs)); TripleAliases.append(begin(MIPSTriples), end(MIPSTriples)); @@ -2701,6 +2711,7 @@ case llvm::Triple::mips64: case llvm::Triple::mips64el: case llvm::Triple::msp430: + case llvm::Triple::m680x0: return true; case llvm::Triple::sparc: case llvm::Triple::sparcel: Index: clang/lib/Driver/ToolChains/Linux.cpp =================================================================== --- clang/lib/Driver/ToolChains/Linux.cpp +++ clang/lib/Driver/ToolChains/Linux.cpp @@ -102,6 +102,12 @@ if (D.getVFS().exists(SysRoot + "/lib/aarch64_be-linux-gnu")) return "aarch64_be-linux-gnu"; break; + + case llvm::Triple::m680x0: + if (D.getVFS().exists(SysRoot + "/lib/m68k-linux-gnu")) + return "m68k-linux-gnu"; + break; + case llvm::Triple::mips: { std::string MT = IsMipsR6 ? "mipsisa32r6-linux-gnu" : "mips-linux-gnu"; if (D.getVFS().exists(SysRoot + "/lib/" + MT)) @@ -472,6 +478,10 @@ Loader = HF ? "ld-linux-armhf.so.3" : "ld-linux.so.3"; break; } + case llvm::Triple::m680x0: + LibDir = "lib"; + Loader = "ld.so.1"; + break; case llvm::Triple::mips: case llvm::Triple::mipsel: case llvm::Triple::mips64: @@ -616,6 +626,8 @@ "/usr/include/armeb-linux-gnueabi"}; const StringRef ARMEBHFMultiarchIncludeDirs[] = { "/usr/include/armeb-linux-gnueabihf"}; + const StringRef M680x0MultiarchIncludeDirs[] = { + "/usr/include/m68k-linux-gnu"}; const StringRef MIPSMultiarchIncludeDirs[] = {"/usr/include/mips-linux-gnu"}; const StringRef MIPSELMultiarchIncludeDirs[] = { "/usr/include/mipsel-linux-gnu"}; @@ -678,6 +690,9 @@ else MultiarchIncludeDirs = ARMEBMultiarchIncludeDirs; break; + case llvm::Triple::m680x0: + MultiarchIncludeDirs = M680x0MultiarchIncludeDirs; + break; case llvm::Triple::mips: if (getTriple().getSubArch() == llvm::Triple::MipsSubArch_r6) MultiarchIncludeDirs = MIPSR6MultiarchIncludeDirs; Index: clang/test/Driver/m680x0-features.cpp =================================================================== --- /dev/null +++ clang/test/Driver/m680x0-features.cpp @@ -0,0 +1,37 @@ +// Check macro definitions +// RUN: %clang -target m680x0-unknown-linux -m68000 -dM -E %s | FileCheck --check-prefix=CHECK-MX %s +// CHECK-MX: #define __mc68000 1 +// CHECK-MX: #define __mc68000__ 1 +// CHECK-MX: #define mc68000 1 + +// RUN: %clang -target m680x0-unknown-linux -m68010 -dM -E %s | FileCheck --check-prefix=CHECK-MX10 %s +// CHECK-MX10: #define __mc68000 1 +// CHECK-MX10: #define __mc68000__ 1 +// CHECK-MX10: #define __mc68010 1 +// CHECK-MX10: #define __mc68010__ 1 +// CHECK-MX10: #define mc68000 1 +// CHECK-MX10: #define mc68010 1 + +// RUN: %clang -target m680x0-unknown-linux -m68020 -dM -E %s | FileCheck --check-prefix=CHECK-MX20 %s +// CHECK-MX20: #define __mc68000 1 +// CHECK-MX20: #define __mc68000__ 1 +// CHECK-MX20: #define __mc68020 1 +// CHECK-MX20: #define __mc68020__ 1 +// CHECK-MX20: #define mc68000 1 +// CHECK-MX20: #define mc68020 1 + +// RUN: %clang -target m680x0-unknown-linux -m68030 -dM -E %s | FileCheck --check-prefix=CHECK-MX30 %s +// CHECK-MX30: #define __mc68000 1 +// CHECK-MX30: #define __mc68000__ 1 +// CHECK-MX30: #define __mc68030 1 +// CHECK-MX30: #define __mc68030__ 1 +// CHECK-MX30: #define mc68000 1 +// CHECK-MX30: #define mc68030 1 + +// RUN: %clang -target m680x0-unknown-linux -m68040 -dM -E %s | FileCheck --check-prefix=CHECK-MX40 %s +// CHECK-MX40: #define __mc68000 1 +// CHECK-MX40: #define __mc68000__ 1 +// CHECK-MX40: #define __mc68040 1 +// CHECK-MX40: #define __mc68040__ 1 +// CHECK-MX40: #define mc68000 1 +// CHECK-MX40: #define mc68040 1 Index: clang/test/Driver/m680x0-sub-archs.cpp =================================================================== --- /dev/null +++ clang/test/Driver/m680x0-sub-archs.cpp @@ -0,0 +1,29 @@ +// RUN: %clang -### -target m680x0-unknown-linux -mcpu=68000 %s 2>&1 | FileCheck --check-prefix=CHECK-MX00 %s +// RUN: %clang -### -target m680x0-unknown-linux -mcpu=m68000 %s 2>&1 | FileCheck --check-prefix=CHECK-MX00 %s +// RUN: %clang -### -target m680x0-unknown-linux -mcpu=M68000 %s 2>&1 | FileCheck --check-prefix=CHECK-MX00 %s +// RUN: %clang -### -target m680x0-unknown-linux -m68000 %s 2>&1 | FileCheck --check-prefix=CHECK-MX00 %s +// CHECK-MX00: "-target-cpu" "M68000" + +// RUN: %clang -### -target m680x0-unknown-linux -mcpu=68010 %s 2>&1 | FileCheck --check-prefix=CHECK-MX10 %s +// RUN: %clang -### -target m680x0-unknown-linux -mcpu=m68010 %s 2>&1 | FileCheck --check-prefix=CHECK-MX10 %s +// RUN: %clang -### -target m680x0-unknown-linux -mcpu=M68010 %s 2>&1 | FileCheck --check-prefix=CHECK-MX10 %s +// RUN: %clang -### -target m680x0-unknown-linux -m68010 %s 2>&1 | FileCheck --check-prefix=CHECK-MX10 %s +// CHECK-MX10: "-target-cpu" "M68010" + +// RUN: %clang -### -target m680x0-unknown-linux -mcpu=68020 %s 2>&1 | FileCheck --check-prefix=CHECK-MX20 %s +// RUN: %clang -### -target m680x0-unknown-linux -mcpu=m68020 %s 2>&1 | FileCheck --check-prefix=CHECK-MX20 %s +// RUN: %clang -### -target m680x0-unknown-linux -mcpu=M68020 %s 2>&1 | FileCheck --check-prefix=CHECK-MX20 %s +// RUN: %clang -### -target m680x0-unknown-linux -m68020 %s 2>&1 | FileCheck --check-prefix=CHECK-MX20 %s +// CHECK-MX20: "-target-cpu" "M68020" + +// RUN: %clang -### -target m680x0-unknown-linux -mcpu=68030 %s 2>&1 | FileCheck --check-prefix=CHECK-MX30 %s +// RUN: %clang -### -target m680x0-unknown-linux -mcpu=m68030 %s 2>&1 | FileCheck --check-prefix=CHECK-MX30 %s +// RUN: %clang -### -target m680x0-unknown-linux -mcpu=M68030 %s 2>&1 | FileCheck --check-prefix=CHECK-MX30 %s +// RUN: %clang -### -target m680x0-unknown-linux -m68030 %s 2>&1 | FileCheck --check-prefix=CHECK-MX30 %s +// CHECK-MX30: "-target-cpu" "M68030" + +// RUN: %clang -### -target m680x0-unknown-linux -mcpu=68040 %s 2>&1 | FileCheck --check-prefix=CHECK-MX40 %s +// RUN: %clang -### -target m680x0-unknown-linux -mcpu=m68040 %s 2>&1 | FileCheck --check-prefix=CHECK-MX40 %s +// RUN: %clang -### -target m680x0-unknown-linux -mcpu=M68040 %s 2>&1 | FileCheck --check-prefix=CHECK-MX40 %s +// RUN: %clang -### -target m680x0-unknown-linux -m68040 %s 2>&1 | FileCheck --check-prefix=CHECK-MX40 %s +// CHECK-MX40: "-target-cpu" "M68040"