[clang] [llvm] [clangd] Add support for the c2000 architecture (PR #125663)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 4 02:24:19 PST 2025
https://github.com/student433 created https://github.com/llvm/llvm-project/pull/125663
Fixes #114979, adding support for the cl2000 compiler to the clang frontend to get clangd working as discussed in https://discourse.llvm.org/t/ti-c2000-target-not-supported-in-clangd-lsp/83015
>From 5906c0f4090e2e9b790401c34ba70eedcbb7f8ae Mon Sep 17 00:00:00 2001
From: Aditya Grewal <Grewal at feo-elektronik.de>
Date: Tue, 4 Feb 2025 10:59:32 +0100
Subject: [PATCH] [clangd] Add support for the c2000 architecture
---
clang/include/clang/Driver/Driver.h | 6 +-
clang/include/clang/Driver/Options.h | 1 +
clang/include/clang/Driver/Options.td | 74 ++++-
clang/lib/Basic/CMakeLists.txt | 1 +
clang/lib/Basic/Targets.cpp | 4 +
clang/lib/Basic/Targets/C2000.cpp | 356 +++++++++++++++++++++
clang/lib/Basic/Targets/C2000.h | 100 ++++++
clang/lib/Driver/CMakeLists.txt | 1 +
clang/lib/Driver/Driver.cpp | 13 +
clang/lib/Driver/ToolChain.cpp | 1 +
clang/lib/Driver/ToolChains/Arch/C2000.cpp | 85 +++++
clang/lib/Driver/ToolChains/Arch/C2000.h | 22 ++
clang/lib/Driver/ToolChains/CommonArgs.cpp | 5 +
llvm/include/llvm/TargetParser/Triple.h | 1 +
llvm/lib/TargetParser/Triple.cpp | 7 +
15 files changed, 666 insertions(+), 11 deletions(-)
create mode 100644 clang/lib/Basic/Targets/C2000.cpp
create mode 100644 clang/lib/Basic/Targets/C2000.h
create mode 100644 clang/lib/Driver/ToolChains/Arch/C2000.cpp
create mode 100644 clang/lib/Driver/ToolChains/Arch/C2000.h
diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h
index f4a52cc529b79cd..55da823598f9b1b 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -107,7 +107,8 @@ class Driver {
CPPMode,
CLMode,
FlangMode,
- DXCMode
+ DXCMode,
+ C2000Mode
} Mode;
enum SaveTempsMode {
@@ -253,6 +254,9 @@ class Driver {
/// Whether the driver should follow dxc.exe like behavior.
bool IsDXCMode() const { return Mode == DXCMode; }
+ // Whether the driver should follow cl2000.exe like behaviour.
+ bool IsC2000Mode() const { return Mode == C2000Mode; }
+
/// Only print tool bindings, don't build any jobs.
LLVM_PREFERRED_TYPE(bool)
unsigned CCCPrintBindings : 1;
diff --git a/clang/include/clang/Driver/Options.h b/clang/include/clang/Driver/Options.h
index 0797410e9940e22..1613810a5bf741c 100644
--- a/clang/include/clang/Driver/Options.h
+++ b/clang/include/clang/Driver/Options.h
@@ -39,6 +39,7 @@ enum ClangVisibility {
FlangOption = (1 << 4),
FC1Option = (1 << 5),
DXCOption = (1 << 6),
+ CL2000Option = (1 << 7)
};
enum ID {
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index d38dd2b4e3cf09f..44ce3c3413b09be 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -97,6 +97,10 @@ def FC1Option : OptionVisibility;
// are made available when the driver is running in DXC compatibility mode.
def DXCOption : OptionVisibility;
+// CL2000Option - This is a cl2000.exe compatibility option. Options with this flag
+// are made available when the driver is running in cl2000 compatibility mode.
+def CL2000Option : OptionVisibility;
+
/////////
// Docs
@@ -201,6 +205,9 @@ def hlsl_Group : OptionGroup<"<HLSL group>">, Group<f_Group>,
DocName<"HLSL options">,
Visibility<[ClangOption]>;
+def cl2000_group : OptionGroup<"<cl2000 group>">,
+ Visibility<[CL2000Option]>;
+
// Feature groups - these take command line options that correspond directly to
// target specific features and can be translated directly from command line
// options.
@@ -672,7 +679,7 @@ class InternalDriverOpt : Group<internal_driver_Group>,
Flags<[NoXarchOption, HelpHidden]>;
def driver_mode : Joined<["--"], "driver-mode=">, Group<internal_driver_Group>,
Flags<[NoXarchOption, HelpHidden]>,
- Visibility<[ClangOption, FlangOption, CLOption, DXCOption]>,
+ Visibility<[ClangOption, FlangOption, CLOption, DXCOption, CL2000Option]>,
HelpText<"Set the driver mode to either 'gcc', 'g++', 'cpp', 'cl' or 'flang'">;
def rsp_quoting : Joined<["--"], "rsp-quoting=">, Group<internal_driver_Group>,
Flags<[NoXarchOption, HelpHidden]>,
@@ -843,7 +850,7 @@ def C : Flag<["-"], "C">, Visibility<[ClangOption, CC1Option]>,
HelpText<"Include comments in preprocessed output">,
MarshallingInfoFlag<PreprocessorOutputOpts<"ShowComments">>;
def D : JoinedOrSeparate<["-"], "D">, Group<Preprocessor_Group>,
- Visibility<[ClangOption, CC1Option, FlangOption, FC1Option, DXCOption]>,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option, DXCOption, CL2000Option]>,
MetaVarName<"<macro>=<value>">,
HelpText<"Define <macro> to <value> (or 1 if <value> omitted)">;
def E : Flag<["-"], "E">, Flags<[NoXarchOption]>,
@@ -929,7 +936,7 @@ def ObjCXX : Flag<["-"], "ObjC++">, Flags<[NoXarchOption]>,
def ObjC : Flag<["-"], "ObjC">, Flags<[NoXarchOption]>,
HelpText<"Treat source input files as Objective-C inputs">;
def O : Joined<["-"], "O">, Group<O_Group>,
- Visibility<[ClangOption, CC1Option, FC1Option, FlangOption]>;
+ Visibility<[ClangOption, CC1Option, FC1Option, FlangOption, CL2000Option]>;
def O_flag : Flag<["-"], "O">, Visibility<[ClangOption, CC1Option, FC1Option]>,
Alias<O>, AliasArgs<["1"]>;
def Ofast : Joined<["-"], "Ofast">, Group<O_Group>,
@@ -1035,10 +1042,10 @@ def Xassembler : Separate<["-"], "Xassembler">,
Group<CompileOnly_Group>;
def Xclang : Separate<["-"], "Xclang">,
HelpText<"Pass <arg> to clang -cc1">, MetaVarName<"<arg>">,
- Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, DXCOption]>,
+ Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, DXCOption, CL2000Option]>,
Group<CompileOnly_Group>;
def : Joined<["-"], "Xclang=">, Group<CompileOnly_Group>,
- Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, DXCOption]>,
+ Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, DXCOption, CL2000Option]>,
Alias<Xclang>,
HelpText<"Alias for -Xclang">, MetaVarName<"<arg>">;
def Xcuda_fatbinary : Separate<["-"], "Xcuda-fatbinary">,
@@ -4023,7 +4030,7 @@ def fdriver_only : Flag<["-"], "fdriver-only">, Flags<[NoXarchOption]>,
Group<Action_Group>, HelpText<"Only run the driver.">;
def fsyntax_only : Flag<["-"], "fsyntax-only">,
Flags<[NoXarchOption]>,
- Visibility<[ClangOption, CLOption, DXCOption, CC1Option, FC1Option, FlangOption]>,
+ Visibility<[ClangOption, CLOption, DXCOption, CC1Option, FC1Option, FlangOption, CL2000Option]>,
Group<Action_Group>,
HelpText<"Run the preprocessor, parser and semantic analysis stages">;
def ftabstop_EQ : Joined<["-"], "ftabstop=">, Group<f_Group>;
@@ -4470,7 +4477,7 @@ defm emit_compact_unwind_non_canonical : BoolFOption<"emit-compact-unwind-non-ca
"Try emitting Compact-Unwind for non-canonical entries. Maybe overridden by other constraints">,
NegFlag<SetFalse>>;
def g_Flag : Flag<["-"], "g">, Group<g_Group>,
- Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
+ Visibility<[ClangOption, CLOption, DXCOption, FlangOption, CL2000Option]>,
HelpText<"Generate source-level debug information">;
def gline_tables_only : Flag<["-"], "gline-tables-only">, Group<gN_Group>,
Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
@@ -5817,11 +5824,11 @@ def rdynamic : Flag<["-"], "rdynamic">, Group<Link_Group>,
Visibility<[ClangOption, FlangOption]>;
def resource_dir : Separate<["-"], "resource-dir">,
Flags<[NoXarchOption, HelpHidden]>,
- Visibility<[ClangOption, CC1Option, CLOption, DXCOption, FlangOption, FC1Option]>,
+ Visibility<[ClangOption, CC1Option, CLOption, DXCOption, FlangOption, FC1Option, CL2000Option]>,
HelpText<"The directory which holds the compiler resource files">,
MarshallingInfoString<HeaderSearchOpts<"ResourceDir">>;
def resource_dir_EQ : Joined<["-"], "resource-dir=">, Flags<[NoXarchOption]>,
- Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
+ Visibility<[ClangOption, CLOption, DXCOption, FlangOption, CL2000Option]>,
Alias<resource_dir>;
def rpath : Separate<["-"], "rpath">, Flags<[LinkerInput]>, Group<Link_Group>,
Visibility<[ClangOption, FlangOption]>;
@@ -6020,7 +6027,7 @@ def w : Flag<["-"], "w">, HelpText<"Suppress all warnings">,
MarshallingInfoFlag<DiagnosticOpts<"IgnoreWarnings">>;
def x : JoinedOrSeparate<["-"], "x">,
Flags<[NoXarchOption]>,
- Visibility<[ClangOption, CC1Option, FlangOption, FC1Option, CLOption]>,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option, CLOption, CL2000Option]>,
HelpText<"Treat subsequent input files as having type <language>">,
MetaVarName<"<language>">;
def y : Joined<["-"], "y">;
@@ -9111,3 +9118,50 @@ def wasm_opt : Flag<["--"], "wasm-opt">,
Group<m_Group>,
HelpText<"Enable the wasm-opt optimizer (default)">,
MarshallingInfoNegativeFlag<LangOpts<"NoWasmOpt">>;
+
+
+
+//===----------------------------------------------------------------------===//
+// cl2000 Options
+//===----------------------------------------------------------------------===//
+
+
+
+
+def cl2000_include_path : Joined<["--"], "include_path=">, Group<cl2000_group>,
+ HelpText<"specify include search paths for cl2000 driver mode">, Alias<isystem>;
+
+def eabi : Joined<["--"], "abi=">, Group<cl2000_group>,
+ HelpText<"abi">;
+def strict_ansi : Joined<["--"], "strict_ansi">, Group<cl2000_group>,
+ HelpText<"strict ANSI/ISO Mode">;
+def fp_mode : Joined<["--"], "fp_mode=">, Group<cl2000_group>,
+ HelpText<"fp mode">;
+def cla_support : Joined<["--"], "cla_support=">, Group<cl2000_group>,
+ HelpText<"cla Support">;
+def float_support : Joined<["--"], "float_support=">, Group<cl2000_group>,
+ HelpText<"Float Support">;
+def idiv_support : Joined<["--"], "idiv_support=">, Group<cl2000_group>,
+ HelpText<"idiv Support">;
+def tmu_support : Joined<["--"], "tmu_support=">, Group<cl2000_group>,
+ HelpText<"tmu Support">;
+def vcu_support : Joined<["--"], "vcu_support=">, Group<cl2000_group>,
+ HelpText<"vcu Support">;
+def opt_level : Joined<["--"], "opt_level=">, Group<cl2000_group>,
+ HelpText<"opt level">, Alias<O>;
+def silicon_version : Joined<["-"], "v28">, Group<cl2000_group>,
+ HelpText<"silicon version">;
+def large_model : Joined<["-"], "ml">, Group<cl2000_group>,
+ HelpText<"large model">;
+def unified_memory : Joined<["-"], "mt">, Group<cl2000_group>,
+ HelpText<"unified memory">;
+def output_file : Joined<["--"], "output_file=">, Group<cl2000_group>,
+ HelpText<"output file">, Alias<o>;
+def source_file : Joined<["--"], "">, Group<cl2000_group>,
+ HelpText<"source file">;
+def symdebug_dwarf : Joined<["--"], "symdebug:dwarf">, Group<cl2000_group>,
+ HelpText<"Alias for -g">, Alias<g_Flag>;
+def relaxed_ansi : Joined<["--"], "relaxed_ansi">, Group<cl2000_group>,
+ HelpText<"relaxed ansi mode">;
+def compile_only : Joined<["--"], "compile_only">, Group<cl2000_group>,
+ HelpText<"compile only">, Alias<c>;
diff --git a/clang/lib/Basic/CMakeLists.txt b/clang/lib/Basic/CMakeLists.txt
index 331dfbb3f4b67e2..bc71f93fe101a29 100644
--- a/clang/lib/Basic/CMakeLists.txt
+++ b/clang/lib/Basic/CMakeLists.txt
@@ -99,6 +99,7 @@ add_clang_library(clangBasic
Targets/ARM.cpp
Targets/AVR.cpp
Targets/BPF.cpp
+ Targets/C2000.cpp
Targets/CSKY.cpp
Targets/DirectX.cpp
Targets/Hexagon.cpp
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index 281aebdb1c35d32..9f5045a73b2d83b 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -19,6 +19,7 @@
#include "Targets/ARM.h"
#include "Targets/AVR.h"
#include "Targets/BPF.h"
+#include "Targets/C2000.h"
#include "Targets/CSKY.h"
#include "Targets/DirectX.h"
#include "Targets/Hexagon.h"
@@ -272,6 +273,9 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
case llvm::Triple::msp430:
return std::make_unique<MSP430TargetInfo>(Triple, Opts);
+ case llvm::Triple::c2000:
+ return std::make_unique<C2000TargetInfo>(Triple, Opts);
+
case llvm::Triple::mips:
switch (os) {
case llvm::Triple::Linux:
diff --git a/clang/lib/Basic/Targets/C2000.cpp b/clang/lib/Basic/Targets/C2000.cpp
new file mode 100644
index 000000000000000..5fe53377f108787
--- /dev/null
+++ b/clang/lib/Basic/Targets/C2000.cpp
@@ -0,0 +1,356 @@
+#include "C2000.h"
+#include "Targets.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/MacroBuilder.h"
+#include "clang/Basic/TargetBuiltins.h"
+
+using namespace clang;
+using namespace clang::targets;
+
+const char *const C2000TargetInfo::GCCRegNames[] = {
+ "ACC", "XAR0", "XAR1", "XAR2", "XAR3", "XAR4", "XAR5", "XAR6", "XAR7"};
+
+ArrayRef<const char *> C2000TargetInfo::getGCCRegNames() const {
+ return llvm::ArrayRef(GCCRegNames);
+}
+
+bool C2000TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
+ DiagnosticsEngine &Diags) {
+
+ for (const auto &Feature : Features) {
+ if (Feature == "+eabi") {
+ eabi = true;
+ continue;
+ }
+ if (Feature == "+strict_ansi") {
+ strict = true;
+ continue;
+ }
+ if (Feature == "+cla_support") {
+ cla_support = true;
+ }
+ if (Feature == "+cla0") {
+ cla0 = true;
+ continue;
+ }
+ if (Feature == "+cla1") {
+ cla1 = true;
+ continue;
+ }
+ if (Feature == "+cla2") {
+ cla2 = true;
+ continue;
+ }
+ if (Feature == "+relaxed") {
+ relaxed = true;
+ continue;
+ }
+ if (Feature == "+fpu64") {
+ fpu64 = true;
+ continue;
+ }
+ if (Feature == "+fpu32") {
+ fpu32 = true;
+ continue;
+ }
+ if (Feature == "+tmu_support") {
+ tmu_support = true;
+ }
+ if (Feature == "+tmu1") {
+ tmu1 = true;
+ continue;
+ }
+ if (Feature == "+idiv0") {
+ idiv0 = true;
+ continue;
+ }
+ if (Feature == "+vcu_support") {
+ vcu_support = true;
+ }
+ if (Feature == "+vcu2") {
+ vcu2 = true;
+ continue;
+ }
+ if (Feature == "+vcrc") {
+ vcrc = true;
+ continue;
+ }
+ if (Feature == "+opt_level") {
+ opt = true;
+ continue;
+ }
+ }
+ return true;
+}
+
+bool C2000TargetInfo::hasFeature(StringRef Feature) const {
+ return llvm::StringSwitch<bool>(Feature)
+ .Case("eabi", eabi)
+ .Case("strict_ansi", strict)
+ .Case("cla-support", cla_support)
+ .Case("cla0", cla0)
+ .Case("cla1", cla1)
+ .Case("cla2", cla2)
+ .Case("relaxed", relaxed)
+ .Case("fpu64", fpu64)
+ .Case("fpu32", fpu32)
+ .Case("tmu-support", tmu_support)
+ .Case("tmu1", tmu1)
+ .Case("vcu-support", vcu_support)
+ .Case("vcu2", vcu2)
+ .Case("vcrc", vcrc)
+ .Case("opt-level", opt)
+ .Default(false);
+}
+
+void C2000TargetInfo::getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ Builder.undefineMacro("__CHAR_BIT__"); // FIXME: Implement 16-bit char
+ Builder.defineMacro("__CHAR_BIT__", "16");
+ Builder.defineMacro("__TMS320C2000__");
+ Builder.defineMacro("_TMS320C2000");
+ Builder.defineMacro("__TMS320C28XX__");
+ Builder.defineMacro("_TMS320C28XX");
+ Builder.defineMacro("__TMS320C28X__");
+ Builder.defineMacro("_TMS320C28X");
+ Builder.defineMacro("__TI_STRICT_FP_MODE__");
+ Builder.defineMacro("__COMPILER_VERSION__");
+ Builder.defineMacro("__TI_COMPILER_VERSION__");
+ Builder.defineMacro("__TI_COMPILER_VERSION__QUAL_ID");
+ Builder.defineMacro("__TI_COMPILER_VERSION__QUAL__", "QUAL_LETTER");
+ Builder.defineMacro("__little_endian__");
+ Builder.defineMacro("__PTRDIFF_T_TYPE__", "signed long");
+ Builder.defineMacro("__SIZE_T_TYPE__", "unsigned long");
+ Builder.defineMacro("__WCHAR_T_TYPE__", "long unsigned");
+ Builder.defineMacro("__TI_WCHAR_T_BITS", "16");
+ Builder.defineMacro("__TI_C99_COMPLEX_ENABLED");
+ Builder.defineMacro("__TI_GNU_ATTRIBUTE_SUPPORT__");
+ Builder.defineMacro("__LARGE_MODEL__");
+ Builder.defineMacro("__signed_chars__");
+ Builder.defineMacro("__OPTIMIZE_FOR_SPACE");
+
+ if (hasFeature("eabi"))
+ Builder.defineMacro("__TI_EABI__");
+ if (hasFeature("strict_ansi"))
+ Builder.defineMacro("__TI_STRICT_ANSI_MODE__");
+ if (hasFeature("cla-support"))
+ Builder.defineMacro("__TMS320C28XX_CLA__");
+
+ if (hasFeature("cla0"))
+ Builder.defineMacro("__TMS320C28XX_CLA0__");
+ else if (hasFeature("cla1"))
+ Builder.defineMacro("__TMS320C28XX_CLA1__");
+ else if (hasFeature("cla2"))
+ Builder.defineMacro("__TMS320C28XX_CLA2__");
+
+ if (hasFeature("fpu64")) {
+ Builder.defineMacro("__TMS320C28XX_FPU64__");
+ Builder.defineMacro("__TMS320C28XX_FPU32__");
+ } else if (hasFeature("fpu32"))
+ Builder.defineMacro("__TMS320C28XX_FPU32__");
+ if (hasFeature("idiv0"))
+ Builder.defineMacro("__TMS320C28XX_IDIV__");
+ if (hasFeature("tmu1"))
+ Builder.defineMacro("__TMS320C28XX_TMU1__");
+ if (hasFeature("tmu-support")) {
+ Builder.defineMacro("__TMS320C28XX_TMU0__");
+ Builder.defineMacro("__TMS320C28XX_TMU__");
+ }
+ if (hasFeature("vcu-support"))
+ Builder.defineMacro("__TMS320C28XX_VCU0__");
+ if (hasFeature("vcu2"))
+ Builder.defineMacro("__TMS320C28XX_VCU2__");
+ else if (hasFeature("vcrc"))
+ Builder.defineMacro("__TMS320C28XX_VCRC__");
+ if (hasFeature("opt-level"))
+ Builder.defineMacro("_INLINE");
+ if (hasFeature("relaxed"))
+ Builder.undefineMacro("__TI_STRICT_FP_MODE__");
+
+ Builder.defineMacro("__cregister", "");
+ Builder.defineMacro("interrupt", "");
+ Builder.defineMacro("__interrupt", "");
+
+ // Assembly Instrinsics
+
+ Builder.append("int __abs16_sat( int src );");
+ Builder.append("void __add( int *m, int b );");
+ Builder.append("long __addcu( long src1, unsigned int src2 );");
+ Builder.append("void __addl( long *m, long b );");
+ Builder.append("void __and(int *m, int b);");
+ Builder.append("int *__byte_func( int *array, unsigned int byte_index );");
+ Builder.defineMacro("__byte(array, byte_index)",
+ "*__byte_func(array, byte_index)");
+ Builder.append("unsigned long *__byte_peripheral_32_func(unsigned long *x);");
+ Builder.defineMacro("__byte_peripheral_32(x)",
+ "*__byte_peripheral_32_func(x)");
+ Builder.append("void __dec( int *m );");
+
+ // dmac needs macro magic
+ Builder.append("unsigned int __disable_interrupts( );");
+ Builder.append("void __eallow( void );");
+ Builder.append("void __edis( void );");
+ Builder.append("unsigned int __enable_interrupts( );");
+ Builder.append("int __flip16(int src);");
+ Builder.append("long __flip32(long src);");
+ Builder.append("long long __flip64(long long src);");
+ Builder.append("void __inc( int *m );");
+ Builder.append("long __IQ( long double A , int N );");
+ Builder.append("long __IQmpy( long A, long B , int N );");
+ Builder.append("long __IQsat( long A, long max, long min );");
+ Builder.append("long __IQxmpy(long A , long B, int N);");
+ Builder.append("long long __llmax(long long dst, long long src);");
+ Builder.append("long long __llmin(long long dst, long long src);");
+ Builder.append("long __lmax(long dst, long src);");
+ Builder.append("long __lmin(long dst, long src);");
+ Builder.append("int __max(int dst, int src);");
+ Builder.append("int __min(int dst, int src);");
+ Builder.append("int __mov_byte( int *src, unsigned int n );");
+ Builder.append("long __mpy( int src1, int src2 );");
+ Builder.append("long __mpyb( int src1, unsigned int src2 );");
+ Builder.append("long __mpy_mov_t( int src1, int src2, int * dst2 );");
+ Builder.append("unsigned long __mpyu(unsigned int src2, unsigned int srt2);");
+ Builder.append("long __mpyxu( int src1, unsigned int src2 );");
+ Builder.append("long __norm32(long src, int * shift );");
+ Builder.append("long long __norm64(long long src, int * shift );");
+ Builder.append("void __or(int *m, int b);");
+ Builder.append("long __qmpy32( long src32a, long src32b, int q );");
+ Builder.append("long __qmpy32by16(long src32, int src16, int q);");
+ Builder.append("void __restore_interrupts(unsigned int val );");
+ Builder.append("long __rol( long src );");
+ Builder.append("long __ror( long src );");
+ Builder.append("void * __rpt_mov_imm(void * dst , int src ,int count );");
+ Builder.append("int __rpt_norm_inc( long src, int dst, int count );");
+ Builder.append("int __rpt_norm_dec(long src, int dst, int count);");
+ Builder.append("long __rpt_rol(long src, int count);");
+ Builder.append("long __rpt_ror(long src, int count);");
+ Builder.append("long __rpt_subcu(long dst, int src, int count);");
+ Builder.append("unsigned long __rpt_subcul(unsigned long num, unsigned long "
+ "den, unsigned long remainder, int count);");
+ Builder.append("long __sat( long src );");
+ Builder.append("long __sat32( long src, long limit );");
+ Builder.append("long __sathigh16(long src, int limit);");
+ Builder.append("long __satlow16( long src );");
+ Builder.append("long __sbbu( long src1 , unsigned int src2 );");
+ Builder.append("void __sub( int * m, int b );");
+ Builder.append("long __subcu( long src1, int src2 );");
+ Builder.append("unsigned long __subcul(unsigned long num, unsigned long den, "
+ "unsigned long remainder);");
+ Builder.append("void __subl( long * m, long b );");
+ Builder.append("void __subr( int * m , int b );");
+ Builder.append("void __subrl( long * m , long b );");
+ Builder.append("int __tbit( int src , int bit );");
+ Builder.append("void __xor( int * m, int b );");
+
+ // FPU Intrinsics
+ if (hasFeature("fpu64")) {
+ Builder.append("double __einvf64( double x );");
+ Builder.append("double __eisqrtf64( double x );");
+ Builder.append("void __f64_max_idx( double dst, double src, double "
+ "idx_dst, double idx_src );");
+ Builder.append("void __f64_min_idx( double dst, double src, double "
+ "idx_dst, double idx_src );");
+ Builder.append("double __fmax64( double x, double y );");
+ Builder.append("double __fmin64( double x, double y );");
+ Builder.append("double __fracf64(double src );");
+ Builder.append("void __swapff( double &a, double &b );");
+ } else {
+ Builder.append("float __eisqrtf32( float x );");
+ Builder.append("void __f32_max_idx( float dst, float src, float idx_dst, "
+ "float idx_src );");
+ Builder.append("void __f32_min_idx( float dst, float src, float idx_dst, "
+ "float idx_src );");
+ Builder.append("int __f32toi16r(float src );");
+ Builder.append("unsigned int __f32toui16r(float src );");
+ Builder.append("float __fmax( float x, float y );");
+ Builder.append("float __fmin( float x, float y );");
+ Builder.append("float __fracf32(float src );");
+ Builder.append("float __fsat(float val, float max, float min );");
+ Builder.append("void __swapf( float &a, float &b );");
+ Builder.append("void __swapff( float &a, float &b );");
+ }
+
+ // Trigonometric Math Unit (TMU) Intrinsics
+ if (hasFeature("tmu-support")) {
+ Builder.append("float __atan( float src );");
+ Builder.append("float __atan2( float y , float x );");
+ Builder.append("float __atanpuf32( float src );");
+ Builder.append("float __atan2puf32( float x, float y );");
+ Builder.append("float __cos( float src );");
+ Builder.append("float __cospuf32( float src );");
+ Builder.append("float __divf32( float num , float denom );");
+ Builder.append("float __div2pif32( float src );");
+ Builder.append("float __mpy2pif32( float src );");
+ Builder.append("float __quadf32( float ratio, float y, float x );");
+ Builder.append("float __sin( float src );");
+ Builder.append("float __sinpuf32( float src );");
+ Builder.append("float __sqrt( float src );");
+ }
+
+ // Fast Integer Division Intrinsics
+ if (hasFeature("idiv-support")) {
+ Builder.append(
+ "ldiv_t __traditional_div_i16byi16( int dividend, int divisor );");
+ Builder.append(
+ "ldiv_t __euclidean_div_i16byi16( int dividend, int divisor );");
+ Builder.append(
+ "ldiv_t __modulo_div_i16byi16( int dividend, int divisor );");
+ Builder.append("_ulldiv_t __traditional_div_u16byu16( unsigned int "
+ "dividend, unsigned int divisor );");
+ Builder.append(
+ "ldiv_t __traditional_div_i32byi32( long dividend, long divisor );");
+ Builder.append(
+ "ldiv_t __euclidean_div_i32byi32( long dividend, long divisor );");
+ Builder.append(
+ "ldiv_t __modulo_div_i32byi32( long dividend, long divisor );");
+ Builder.append("ldiv_t __traditional_div_i32byu32( long dividend, unsigned "
+ "long divisor );");
+ Builder.append("ldiv_t __euclidean_div_i32byu32( long dividend, unsigned "
+ "long divisor );");
+ Builder.append("ldiv_t __modulo_div_i32byu32( long dividend, unsigned long "
+ "divisor );");
+ Builder.append("_ulldiv_t __traditional_div_u32byu32( unsigned long "
+ "dividend, unsigned long divisor );");
+ Builder.append(
+ "ldiv_t __traditional_div_i32byi16( long dividend, int divisor );");
+ Builder.append(
+ "ldiv_t __euclidean_div_i32byi16( long dividend, int divisor );");
+ Builder.append(
+ "ldiv_t __modulo_div_i32byi16( long dividend, int divisor );");
+ Builder.append("lldiv_t __traditional_div_i64byi64( long long dividend, "
+ "long long divisor );");
+ Builder.append("lldiv_t __euclidean_div_i64byi64( long long dividend, long "
+ "long divisor );");
+ Builder.append("lldiv_t __modulo_div_i64byi64( long long dividend, long "
+ "long divisor );");
+ Builder.append("lldiv_t __traditional_div_i64byu64( long long dividend, "
+ "unsigned long long divisor );");
+ Builder.append("lldiv_t __euclidean_div_i64byu64( long long dividend, "
+ "unsigned long long divisor );");
+ Builder.append("lldiv_t __modulo_div_i64byu64( long long dividend, "
+ "unsigned long long divisor );");
+ Builder.append("__ulldiv_t __traditional_div_u64byu64( unsigned long long "
+ "dividend, unsigned long long divisor );");
+ Builder.append("lldiv_t __traditional_div_i64byi32( signed long long "
+ "dividend, long divisor);");
+ Builder.append("lldiv_t __euclidean_div_i64byi32( signed long long "
+ "dividend, long divisor );");
+ Builder.append("lldiv_t __modulo_div_i64byi32( signed long long dividend, "
+ "long divisor );");
+ Builder.append("lldiv_t __traditional_div_i64byu32( signed long long "
+ "dividend, unsigned long divisor );");
+ Builder.append("lldiv_t __euclidean_div_i64byu32( signed long long "
+ "dividend, unsigned long divisor );");
+ Builder.append("lldiv_t __modulo_div_i64byu32( unsigned long long "
+ "dividend, unsigned long divisor );");
+ Builder.append("__ulldiv_t __traditional_div_u64byu32( unsigned long long "
+ "dividend, unsigned long divisor );");
+ }
+
+ // Non-documented intrinsics
+ Builder.append("void *memcpy(void * __restrict s1, const void * __restrict "
+ "s2, unsigned long n);");
+ Builder.defineMacro("__intaddr__(x)", "x");
+ Builder.defineMacro("asm(x)", "");
+}
diff --git a/clang/lib/Basic/Targets/C2000.h b/clang/lib/Basic/Targets/C2000.h
new file mode 100644
index 000000000000000..e1b8e2388390154
--- /dev/null
+++ b/clang/lib/Basic/Targets/C2000.h
@@ -0,0 +1,100 @@
+#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_C2000_H
+#define LLVM_CLANG_LIB_BASIC_TARGETS_C2000_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
+
+namespace clang {
+namespace targets {
+
+class C2000TargetInfo : public TargetInfo {
+ static const char *const GCCRegNames[];
+ bool eabi = false;
+ bool strict = false;
+ bool opt = false;
+ bool fpu64 = false;
+ bool fpu32 = false;
+ bool relaxed = false;
+ bool tmu_support = false;
+ bool cla_support = false;
+ bool vcu_support = false;
+ bool cla0 = false;
+ bool cla1 = false;
+ bool cla2 = false;
+ bool vcu2 = false;
+ bool vcrc = false;
+ bool tmu1 = false;
+ bool idiv0 = false;
+
+public:
+ C2000TargetInfo(const llvm::Triple &Triple, const TargetOptions &)
+ : TargetInfo(Triple) {
+ TLSSupported = false;
+ BigEndian = false;
+ BoolWidth = BoolAlign = 16;
+ IntWidth = IntAlign = 16;
+ LongLongWidth = 64;
+ LongLongAlign = 32;
+ FloatWidth = FloatAlign = 32;
+ DoubleWidth = 64;
+ DoubleAlign = 32;
+ LongDoubleWidth = 64;
+ LongDoubleAlign = 32;
+ PointerWidth = 32;
+ PointerAlign = 16;
+ Char16Type = UnsignedShort;
+ Char32Type = UnsignedLong;
+ SizeType = UnsignedLong;
+ PtrDiffType = SignedLong;
+ WCharType = UnsignedLong;
+ WIntType = UnsignedLong;
+ IntMaxType = SignedLongLong;
+ IntPtrType = SignedInt;
+ resetDataLayout(
+ "e-m:e-p:32:16-i16:16-i32:32-i64:32-f32:32-f64:32-a:8-n16:32-S32");
+ }
+
+ bool handleTargetFeatures(std::vector<std::string> &Features,
+ DiagnosticsEngine &Diags) override;
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+
+ ArrayRef<Builtin::Info> getTargetBuiltins() const override { return {}; }
+
+ bool hasFeature(StringRef Feature) const override;
+
+ ArrayRef<const char *> getGCCRegNames() const override;
+
+ ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
+ // Make these be recognized by llc (f.e., in clobber list)
+ static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
+ {{"xt"}, "mr"}, {{"p"}, "pr"}, {{"dp"}, "dpp"}, {{"sp"}, "sp"},
+ {{"pc"}, "pc"}, {{"rpc"}, "rpc"}, {{"st0"}, "sr"}, {{"ifr"}, "icr"},
+ };
+ return llvm::ArrayRef(GCCRegAliases);
+ }
+
+ bool validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &info) const override {
+
+ return false;
+ }
+
+ std::string_view getClobbers() const override {
+ // FIXME: Is this really right?
+ return "";
+ }
+
+ BuiltinVaListKind getBuiltinVaListKind() const override {
+ // FIXME: implement
+ return TargetInfo::CharPtrBuiltinVaList;
+ }
+};
+
+} // namespace targets
+} // namespace clang
+
+#endif
diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt
index 5bdb6614389cffc..d519ef1df07f336 100644
--- a/clang/lib/Driver/CMakeLists.txt
+++ b/clang/lib/Driver/CMakeLists.txt
@@ -31,6 +31,7 @@ add_clang_library(clangDriver
ToolChain.cpp
ToolChains/Arch/AArch64.cpp
ToolChains/Arch/ARM.cpp
+ ToolChains/Arch/C2000.cpp
ToolChains/Arch/CSKY.cpp
ToolChains/Arch/LoongArch.cpp
ToolChains/Arch/M68k.cpp
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 87855fdb7997105..9ccccda2ed2f487 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -301,6 +301,7 @@ void Driver::setDriverMode(StringRef Value) {
.Case("cl", CLMode)
.Case("flang", FlangMode)
.Case("dxc", DXCMode)
+ .Case("cl2000", C2000Mode)
.Default(std::nullopt))
Mode = *M;
else
@@ -1571,6 +1572,13 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
} else {
Diag(diag::err_drv_dxc_missing_target_profile);
}
+ } else if (IsC2000Mode()) {
+ llvm::Triple T(TargetTriple);
+ T.setArch(llvm::Triple::c2000);
+ T.setVendor(llvm::Triple::UnknownVendor);
+ T.setOS(llvm::Triple::UnknownOS);
+ T.setEnvironment(llvm::Triple::EABI);
+ TargetTriple = T.str();
}
if (const Arg *A = Args.getLastArg(options::OPT_target))
@@ -6942,6 +6950,9 @@ Driver::getOptionVisibilityMask(bool UseDriverMode) const {
if (IsFlangMode()) {
return llvm::opt::Visibility(options::FlangOption);
}
+ if (IsC2000Mode()) {
+ return llvm::opt::Visibility(options::CL2000Option);
+ }
return llvm::opt::Visibility(options::ClangOption);
}
@@ -6959,6 +6970,8 @@ const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
return "flang";
case DXCMode:
return "clang-dxc";
+ case C2000Mode:
+ return "cl2000";
}
llvm_unreachable("Unhandled Mode");
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index acf9d264d631b33..452f0852bc3c621 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -430,6 +430,7 @@ static const DriverSuffix *FindDriverSuffix(StringRef ProgName, size_t &Pos) {
// `flang-new`. This will be removed in the future.
{"flang-new", "--driver-mode=flang"},
{"clang-dxc", "--driver-mode=dxc"},
+ {"cl2000", "--driver-mode=cl2000"},
};
for (const auto &DS : DriverSuffixes) {
diff --git a/clang/lib/Driver/ToolChains/Arch/C2000.cpp b/clang/lib/Driver/ToolChains/Arch/C2000.cpp
new file mode 100644
index 000000000000000..dc3f15b086ceb3d
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/Arch/C2000.cpp
@@ -0,0 +1,85 @@
+#include "C2000.h"
+#include "ToolChains/CommonArgs.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/InputInfo.h"
+#include "clang/Driver/Multilib.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+void c2000::getC2000TargetFeatures(const Driver &D, const ArgList &Args,
+ std::vector<StringRef> &Features) {
+
+ for (auto *A : Args) {
+ if (A->getOption().matches(options::OPT_eabi)) {
+ StringRef abi = A->getValue();
+ if (abi.starts_with("eabi"))
+ Features.push_back("+eabi");
+ continue;
+ }
+ if (A->getOption().matches(options::OPT_relaxed_ansi)) {
+ Features.push_back("+relaxed_ansi");
+ continue;
+ }
+ if (A->getOption().matches(options::OPT_fp_mode)) {
+ StringRef fp_mode = A->getValue();
+ if (fp_mode.starts_with("relaxed"))
+ Features.push_back("+relaxed");
+ continue;
+ }
+ if (A->getOption().matches(options::OPT_cla_support)) {
+ Features.push_back("+cla_support");
+ StringRef cla_support = A->getValue();
+ if (cla_support.starts_with("cla0"))
+ Features.push_back("+cla0");
+ else if (cla_support.starts_with("cla0"))
+ Features.push_back("+cla1");
+ else if (cla_support.starts_with("cla2"))
+ Features.push_back("+cla2");
+ continue;
+ }
+ if (A->getOption().matches(options::OPT_float_support)) {
+ StringRef float_support = A->getValue();
+ if (float_support.starts_with("fpu64"))
+ Features.push_back("+fpu64");
+ else if (float_support.starts_with("fpu32"))
+ Features.push_back("+fpu32");
+ continue;
+ }
+ if (A->getOption().matches(options::OPT_idiv_support)) {
+ StringRef idiv_support = A->getValue();
+ if (idiv_support.starts_with("idiv0"))
+ Features.push_back("+idiv0");
+ continue;
+ }
+ if (A->getOption().matches(options::OPT_tmu_support)) {
+ Features.push_back("+tmu_support");
+ StringRef tmu_support = A->getValue();
+ if (tmu_support.starts_with("tmu1"))
+ Features.push_back("+tmu1");
+ continue;
+ }
+ if (A->getOption().matches(options::OPT_vcu_support)) {
+ Features.push_back("+vcu_support");
+ StringRef vcu_support = A->getValue();
+ if (vcu_support.starts_with("vcu2"))
+ Features.push_back("+vcu2");
+ else if (vcu_support.starts_with("vcrc"))
+ Features.push_back("+vcrc");
+ continue;
+ }
+ if (A->getOption().matches(options::OPT_opt_level)) {
+ StringRef opt_level = A->getValue();
+ if (!opt_level.starts_with("off"))
+ Features.push_back("+opt_level");
+ } else if (A->getOption().matches(options::OPT_O)) {
+ Features.push_back("+opt_level");
+ }
+ }
+}
diff --git a/clang/lib/Driver/ToolChains/Arch/C2000.h b/clang/lib/Driver/ToolChains/Arch/C2000.h
new file mode 100644
index 000000000000000..3cd6ebd754aece5
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/Arch/C2000.h
@@ -0,0 +1,22 @@
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/InputInfo.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/Option.h"
+
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace driver {
+namespace tools {
+namespace c2000 {
+
+void getC2000TargetFeatures(const Driver &D, const llvm::opt::ArgList &Args,
+ std::vector<llvm::StringRef> &Features);
+} // end namespace c2000
+} // end namespace tools
+} // end namespace driver
+} // end namespace clang
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index f8967890f722cf8..848a05135fd8ca9 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -9,6 +9,7 @@
#include "CommonArgs.h"
#include "Arch/AArch64.h"
#include "Arch/ARM.h"
+#include "Arch/C2000.h"
#include "Arch/CSKY.h"
#include "Arch/LoongArch.h"
#include "Arch/M68k.h"
@@ -23,6 +24,7 @@
#include "HIPAMD.h"
#include "Hexagon.h"
#include "MSP430.h"
+
#include "Solaris.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/CodeGenOptions.h"
@@ -788,6 +790,9 @@ void tools::getTargetFeatures(const Driver &D, const llvm::Triple &Triple,
case llvm::Triple::m68k:
m68k::getM68kTargetFeatures(D, Triple, Args, Features);
break;
+ case llvm::Triple::c2000:
+ c2000::getC2000TargetFeatures(D, Args, Features);
+ break;
case llvm::Triple::msp430:
msp430::getMSP430TargetFeatures(D, Args, Features);
break;
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index 8097300c6e630c1..82e8e5a444766f9 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -55,6 +55,7 @@ class Triple {
avr, // AVR: Atmel AVR microcontroller
bpfel, // eBPF or extended BPF or 64-bit BPF (little endian)
bpfeb, // eBPF or extended BPF or 64-bit BPF (big endian)
+ c2000, // C2000 MCU Family
csky, // CSKY: csky
dxil, // DXIL 32-bit DirectX bytecode
hexagon, // Hexagon: hexagon
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index ed58e72089839bb..0e3f2cfa4277d43 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -37,6 +37,7 @@ StringRef Triple::getArchTypeName(ArchType Kind) {
case avr: return "avr";
case bpfeb: return "bpfeb";
case bpfel: return "bpfel";
+ case c2000: return "c2000";
case csky: return "csky";
case dxil: return "dxil";
case hexagon: return "hexagon";
@@ -582,6 +583,7 @@ static Triple::ArchType parseArch(StringRef ArchName) {
.Case("avr", Triple::avr)
.Case("m68k", Triple::m68k)
.Case("msp430", Triple::msp430)
+ .Case("c2000", Triple::c2000)
.Cases("mips", "mipseb", "mipsallegrex", "mipsisa32r6", "mipsr6",
Triple::mips)
.Cases("mipsel", "mipsallegrexel", "mipsisa32r6el", "mipsr6el",
@@ -939,6 +941,7 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
case Triple::avr:
case Triple::bpfeb:
case Triple::bpfel:
+ case Triple::c2000:
case Triple::csky:
case Triple::hexagon:
case Triple::hsail64:
@@ -1652,6 +1655,7 @@ unsigned Triple::getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
case llvm::Triple::arc:
case llvm::Triple::arm:
case llvm::Triple::armeb:
+ case llvm::Triple::c2000:
case llvm::Triple::csky:
case llvm::Triple::dxil:
case llvm::Triple::hexagon:
@@ -1742,6 +1746,7 @@ Triple Triple::get32BitArchVariant() const {
case Triple::arc:
case Triple::arm:
case Triple::armeb:
+ case Triple::c2000:
case Triple::csky:
case Triple::dxil:
case Triple::hexagon:
@@ -1808,6 +1813,7 @@ Triple Triple::get64BitArchVariant() const {
case Triple::UnknownArch:
case Triple::arc:
case Triple::avr:
+ case Triple::c2000:
case Triple::csky:
case Triple::dxil:
case Triple::hexagon:
@@ -1994,6 +2000,7 @@ bool Triple::isLittleEndian() const {
case Triple::arm:
case Triple::avr:
case Triple::bpfel:
+ case Triple::c2000:
case Triple::csky:
case Triple::dxil:
case Triple::hexagon:
More information about the cfe-commits
mailing list