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 <gre...@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: _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits