From 94df5b6ef1854355faceda2f76df142120a04d82 Mon Sep 17 00:00:00 2001
From: Christoph Seitz <christoph.seitz@infineon.com>
Date: Wed, 20 Jul 2022 12:11:03 +0200
Subject: Tasking: Add support for several compiler toolsets

Add support for the Tasking compiler toolset:

* TriCore Compiler Toolset 6.3 (with TriCore, ARM, MCS,
  8051 and PCP architecture compilers)
* SmartCode Compiler Toolset 10.1 (with TriCore, ARC, MCS,
  8051 architecture compilers)
* ARM Compiler 6.0
* MCS Complier 3.3
* 8051 Compiler 7.2

Fixes: #23756
---
 Help/manual/cmake-variables.7.rst                |  1 +
 Help/release/dev/add_tasking_compiler.rst        |  8 +++
 Help/variable/CMAKE_LANG_COMPILER_ID.rst         |  2 +
 Help/variable/CMAKE_TASKING_TOOLSET.rst          | 31 +++++++++
 Modules/CMakeCXXCompilerId.cpp.in                |  1 +
 Modules/CMakeCompilerIdDetection.cmake           |  1 +
 Modules/CMakePlatformId.h.in                     | 24 +++++++
 Modules/Compiler/Tasking-ASM.cmake               |  7 ++
 Modules/Compiler/Tasking-C.cmake                 | 47 +++++++++++++
 Modules/Compiler/Tasking-CXX.cmake               | 31 +++++++++
 Modules/Compiler/Tasking-DetermineCompiler.cmake | 10 +++
 Modules/Compiler/Tasking-FindBinUtils.cmake      | 18 +++++
 Modules/Compiler/Tasking.cmake                   | 86 ++++++++++++++++++++++++
 13 files changed, 267 insertions(+)
 create mode 100644 Help/release/dev/add_tasking_compiler.rst
 create mode 100644 Help/variable/CMAKE_TASKING_TOOLSET.rst
 create mode 100644 Modules/Compiler/Tasking-ASM.cmake
 create mode 100644 Modules/Compiler/Tasking-C.cmake
 create mode 100644 Modules/Compiler/Tasking-CXX.cmake
 create mode 100644 Modules/Compiler/Tasking-DetermineCompiler.cmake
 create mode 100644 Modules/Compiler/Tasking-FindBinUtils.cmake
 create mode 100644 Modules/Compiler/Tasking.cmake

diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 6533ca5..ebebc1a 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -510,6 +510,7 @@ Variables that Control the Build
    /variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG
    /variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG_INIT
    /variable/CMAKE_STATIC_LINKER_FLAGS_INIT
+   /variable/CMAKE_TASKING_TOOLSET
    /variable/CMAKE_TRY_COMPILE_CONFIGURATION
    /variable/CMAKE_TRY_COMPILE_NO_PLATFORM_VARIABLES
    /variable/CMAKE_TRY_COMPILE_PLATFORM_VARIABLES
diff --git a/Help/release/dev/add_tasking_compiler.rst b/Help/release/dev/add_tasking_compiler.rst
new file mode 100644
index 0000000..705f923
--- /dev/null
+++ b/Help/release/dev/add_tasking_compiler.rst
@@ -0,0 +1,8 @@
+add_tasking_compiler
+--------------------
+
+ * Support for the `Tasking compiler toolsets`_ (SmartCode, TriCore,
+   Standalone: ARM, MCS, 8051) was added with compiler id ``Tasking``.
+   See the :variable:`CMAKE_TASKING_TOOLSET` variable.
+
+.. _`Tasking compiler toolsets`: https://tasking.com
diff --git a/Help/variable/CMAKE_LANG_COMPILER_ID.rst b/Help/variable/CMAKE_LANG_COMPILER_ID.rst
index f0534ba..0dbc0a0 100644
--- a/Help/variable/CMAKE_LANG_COMPILER_ID.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER_ID.rst
@@ -44,6 +44,7 @@ Value                           Name
 ``XL``, ``VisualAge``, ``zOS``  IBM XL
 ``XLClang``                     IBM Clang-based XL
 ``IBMClang``                    IBM LLVM-based Compiler
+``Tasking``                     `Tasking Compiler Toolsets`_
 =============================== ===============================================
 
 This variable is not guaranteed to be defined for all compilers or
@@ -63,3 +64,4 @@ languages.
 .. _Open Watcom: https://open-watcom.github.io
 .. _Small Device C Compiler: http://sdcc.sourceforge.net
 .. _Tiny C Compiler: https://bellard.org/tcc
+.. _Tasking Compiler Toolsets: https://tasking.com
diff --git a/Help/variable/CMAKE_TASKING_TOOLSET.rst b/Help/variable/CMAKE_TASKING_TOOLSET.rst
new file mode 100644
index 0000000..430207e
--- /dev/null
+++ b/Help/variable/CMAKE_TASKING_TOOLSET.rst
@@ -0,0 +1,31 @@
+CMAKE_TASKING_TOOLSET
+---------------------
+
+.. versionadded:: 3.25
+
+Select the Tasking toolset which provides the compiler
+
+Architecture compilers are provided by different toolchains with
+incompatible versioning schemes.  Set this variable in a
+:variable:`toolchain file <CMAKE_TOOLCHAIN_FILE>` so CMake can detect
+the compiler and version correctly. If no toolset is specified,
+``Standalone`` is assumed.
+
+Projects, that can be build with different architectures and/or toolsets, must
+take :variable:`CMAKE_TASKING_TOOLSET` and
+:variable:`CMAKE_<LANG>_COMPILER_ARCHITECTURE_ID` into account to qualify
+:variable:`CMAKE_<LANG>_COMPILER_VERSION`.
+
+``TriCore``
+  Compilers are provided by the TriCore toolset.
+
+``SmartCode``
+  Compilers are provided by the SmartCode toolset.
+
+``Standalone``
+  Compilers are provided by the standalone toolsets.
+
+  .. note::
+
+    For the TriCore architecture, the compiler from the TriCore toolset is
+    selected as standalone compiler.
diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in
index f19bc97..2643326 100644
--- a/Modules/CMakeCXXCompilerId.cpp.in
+++ b/Modules/CMakeCXXCompilerId.cpp.in
@@ -82,6 +82,7 @@ int main(int argc, char* argv[])
   int require = 0;
   require += info_compiler[argc];
   require += info_platform[argc];
+  require += info_arch[argc];
 #ifdef COMPILER_VERSION_MAJOR
   require += info_version[argc];
 #endif
diff --git a/Modules/CMakeCompilerIdDetection.cmake b/Modules/CMakeCompilerIdDetection.cmake
index f15974a..75d33e8 100644
--- a/Modules/CMakeCompilerIdDetection.cmake
+++ b/Modules/CMakeCompilerIdDetection.cmake
@@ -70,6 +70,7 @@ function(compiler_id_detection outvar lang)
       FujitsuClang
       Fujitsu
       GHS
+      Tasking
     )
     if ("x${lang}" STREQUAL "xC")
       list(APPEND ordered_compilers
diff --git a/Modules/CMakePlatformId.h.in b/Modules/CMakePlatformId.h.in
index 06f5ecd..32b7166 100644
--- a/Modules/CMakePlatformId.h.in
+++ b/Modules/CMakePlatformId.h.in
@@ -242,6 +242,30 @@
 # elif defined(__ADSPBLACKFIN__)
 #  define ARCHITECTURE_ID "Blackfin"
 
+#elif defined(__TASKING__)
+
+# if defined(__CTC__) || defined(__CPTC__)
+#  define ARCHITECTURE_ID "TriCore"
+
+# elif defined(__CMCS__)
+#  define ARCHITECTURE_ID "MCS"
+
+# elif defined(__CARM__)
+#  define ARCHITECTURE_ID "ARM"
+
+# elif defined(__CARC__)
+#  define ARCHITECTURE_ID "ARC"
+
+# elif defined(__C51__)
+#  define ARCHITECTURE_ID "8051"
+
+# elif defined(__CPCP__)
+#  define ARCHITECTURE_ID "PCP"
+
+# else
+#  define ARCHITECTURE_ID ""
+# endif
+
 #else
 #  define ARCHITECTURE_ID
 #endif
diff --git a/Modules/Compiler/Tasking-ASM.cmake b/Modules/Compiler/Tasking-ASM.cmake
new file mode 100644
index 0000000..19bce19
--- /dev/null
+++ b/Modules/Compiler/Tasking-ASM.cmake
@@ -0,0 +1,7 @@
+include(Compiler/Tasking)
+
+set(CMAKE_ASM_OUTPUT_EXTENSION ".o")
+set(CMAKE_ASM_OUTPUT_EXTENSION_REPLACE 1)
+
+set(CMAKE_ASM_COMPILE_OBJECT       "<CMAKE_ASM_COMPILER> <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>")
+set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS S;s;asm;msa)
diff --git a/Modules/Compiler/Tasking-C.cmake b/Modules/Compiler/Tasking-C.cmake
new file mode 100644
index 0000000..0ea3cd2
--- /dev/null
+++ b/Modules/Compiler/Tasking-C.cmake
@@ -0,0 +1,47 @@
+include(Compiler/Tasking)
+__compiler_tasking(C)
+
+set(CMAKE_C90_STANDARD_COMPILE_OPTION "--iso=90" "--strict")
+set(CMAKE_C90_EXTENSION_COMPILE_OPTION "--iso=90" " ")
+
+set(CMAKE_C99_STANDARD_COMPILE_OPTION "--iso=99" "--strict")
+set(CMAKE_C99_EXTENSION_COMPILE_OPTION "--iso=99" " ")
+
+set(CMAKE_C11_STANDARD_COMPILE_OPTION "--iso=11" "--strict")
+set(CMAKE_C11_EXTENSION_COMPILE_OPTION "--iso=11" " ")
+
+if(CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "TriCore")
+  if(CMAKE_TASKING_TOOLSET STREQUAL "SmartCode")
+    __compiler_check_default_language_standard(C 10.1 11)
+  else()
+    __compiler_check_default_language_standard(C 6.3 11)
+  endif()
+elseif(CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "ARM")
+  if(CMAKE_TASKING_TOOLSET STREQUAL "SmartCode")
+    __compiler_check_default_language_standard(C 10.1 11)
+  elseif(CMAKE_TASKING_TOOLSET STREQUAL "TriCore")
+    __compiler_check_default_language_standard(C 6.3 11)
+  else()
+    __compiler_check_default_language_standard(C 6.0 11)
+  endif()
+elseif(CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "MCS")
+  if(CMAKE_TASKING_TOOLSET STREQUAL "SmartCode")
+    __compiler_check_default_language_standard(C 10.1 11)
+  elseif(CMAKE_TASKING_TOOLSET STREQUAL "TriCore")
+    __compiler_check_default_language_standard(C 6.3 11)
+  else()
+    __compiler_check_default_language_standard(C 3.3 11)
+  endif()
+elseif(CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "ARC")
+  __compiler_check_default_language_standard(C 10.1 11)
+elseif(CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "8051")
+  if(CMAKE_TASKING_TOOLSET STREQUAL "SmartCode")
+    __compiler_check_default_language_standard(C 10.1 11)
+  elseif(CMAKE_TASKING_TOOLSET STREQUAL "TriCore")
+    __compiler_check_default_language_standard(C 6.3 11)
+  else()
+    __compiler_check_default_language_standard(C 7.2 89)
+  endif()
+elseif(CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "PCP")
+  __compiler_check_default_language_standard(C 6.3 11)
+endif()
diff --git a/Modules/Compiler/Tasking-CXX.cmake b/Modules/Compiler/Tasking-CXX.cmake
new file mode 100644
index 0000000..635104c
--- /dev/null
+++ b/Modules/Compiler/Tasking-CXX.cmake
@@ -0,0 +1,31 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+include(Compiler/Tasking)
+__compiler_tasking(CXX)
+
+set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "--c++=03" "--strict")
+set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "--iso=03" " ")
+
+set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "--c++=11" "--strict")
+set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "--c++=11" " ")
+
+set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "--c++=14" "--strict")
+set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "--c++=14" " ")
+
+if(CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "TriCore")
+  if(CMAKE_TASKING_TOOLSET STREQUAL "SmartCode")
+    __compiler_check_default_language_standard(CXX 10.1 14)
+  else()
+    __compiler_check_default_language_standard(CXX 6.3 14)
+  endif()
+elseif(CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "ARM")
+  if(CMAKE_TASKING_TOOLSET STREQUAL "SmartCode")
+    __compiler_check_default_language_standard(CXX 10.1 14)
+  elseif(CMAKE_TASKING_TOOLSET STREQUAL "TriCore")
+    __compiler_check_default_language_standard(CXX 6.3 14)
+  else()
+    __compiler_check_default_language_standard(CXX 6.0 14)
+  endif()
+else()
+  message(FATAL_ERROR "CXX is not supported with the ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID} architecture.")
+endif()
diff --git a/Modules/Compiler/Tasking-DetermineCompiler.cmake b/Modules/Compiler/Tasking-DetermineCompiler.cmake
new file mode 100644
index 0000000..a40be19
--- /dev/null
+++ b/Modules/Compiler/Tasking-DetermineCompiler.cmake
@@ -0,0 +1,10 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+set(_compiler_id_pp_test "defined(__TASKING__)")
+
+set(_compiler_id_version_compute "
+  # define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__VERSION__/1000)
+  # define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__VERSION__ % 100)")
+
+string(APPEND _compiler_id_version_compute "
+# define @PREFIX@COMPILER_VERSION_INTERNAL @MACRO_DEC@(__VERSION__)")
diff --git a/Modules/Compiler/Tasking-FindBinUtils.cmake b/Modules/Compiler/Tasking-FindBinUtils.cmake
new file mode 100644
index 0000000..eab31d7
--- /dev/null
+++ b/Modules/Compiler/Tasking-FindBinUtils.cmake
@@ -0,0 +1,18 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# Find the archiver for the compiler architecture, which is always in the same
+# directory as the compiler.
+if(NOT DEFINED _CMAKE_PROCESSING_LANGUAGE OR _CMAKE_PROCESSING_LANGUAGE STREQUAL "")
+  message(FATAL_ERROR "Internal error: _CMAKE_PROCESSING_LANGUAGE is not set")
+endif()
+
+get_filename_component(__tasking_hints "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER}" DIRECTORY)
+
+find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_AR
+  NAMES artc ararm armcs ar51 ararc arpcp
+  HINTS ${__tasking_hints}
+  NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH
+  DOC "Tasking Archiver"
+)
+mark_as_advanced(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_AR)
diff --git a/Modules/Compiler/Tasking.cmake b/Modules/Compiler/Tasking.cmake
new file mode 100644
index 0000000..30d4c69
--- /dev/null
+++ b/Modules/Compiler/Tasking.cmake
@@ -0,0 +1,86 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# This module is shared by multiple languages; use include blocker.
+if(_Tasking_CMAKE_LOADED)
+  return()
+endif()
+set(_Tasking_CMAKE_LOADED TRUE)
+include(Compiler/CMakeCommonCompilerMacros)
+
+set(CMAKE_EXECUTABLE_SUFFIX ".elf")
+set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
+set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+
+set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
+set(BUILD_SHARED_LIBS FALSE CACHE BOOL "")
+set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
+set(CMAKE_LINK_SEARCH_START_STATIC TRUE)
+
+function(__tasking_set_processor_list lang out_var)
+  execute_process(COMMAND "${CMAKE_${lang}_COMPILER}" --cpu-list
+    OUTPUT_VARIABLE processor_list
+    ERROR_VARIABLE processor_list)
+  string(REGEX MATCHALL "[ ]+([A-Za-z0-9_]+)[ ]+[^ ]([^ ]+ ?)*[ ]+[A-Za-z0-9\\.]+[ ]+[A-Za-z0-9\.]+\n" processor_list "${processor_list}")
+  list(POP_FRONT processor_list)
+  string(REGEX REPLACE "[ ]+([A-Za-z0-9_]+)[ ]+[^ ]([^ ]+ ?)*[ ]+[A-Za-z0-9\\.]+[ ]+[A-Za-z0-9\.]+\n" "\\1" processor_list "${processor_list}")
+  set(${out_var} "${processor_list}" PARENT_SCOPE)
+endfunction()
+
+function(__tasking_check_processor processor list out_var)
+  string(TOLOWER "${processor}" processor)
+  if(processor IN_LIST list)
+    set(${out_var} TRUE PARENT_SCOPE)
+  else()
+    set(${out_var} FALSE PARENT_SCOPE)
+  endif()
+endfunction()
+
+if(NOT CMAKE_TASKING_TOOLSET)
+  set(CMAKE_TASKING_TOOLSET "Standalone")
+endif()
+
+macro(__compiler_tasking lang)
+
+  if(CMAKE_SYSTEM_PROCESSOR)
+    if(NOT _TASKING_${lang}_PROCESSOR_LIST)
+      __tasking_set_processor_list(${lang} _TASKING_${lang}_PROCESSOR_LIST)
+    endif()
+    __tasking_check_processor(${CMAKE_SYSTEM_PROCESSOR} "${_TASKING_${lang}_PROCESSOR_LIST}" _TASKING_${lang}_VALID_PROCESSOR)
+    if(${_TASKING_${lang}_VALID_PROCESSOR})
+      string(APPEND CMAKE_${lang}_FLAGS_INIT " -C${CMAKE_SYSTEM_PROCESSOR}")
+    else()
+      message(FATAL_ERROR "Invalid processor ${CMAKE_SYSTEM_PROCESSOR} specified.\n"
+        "Supported processors: ${_TASKING_${lang}_PROCESSOR_LIST}")
+    endif()
+  endif()
+
+  set(CMAKE_${lang}_VERBOSE_FLAG "-v")
+  set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC")
+  set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Wl" " ")
+  set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "-f ")
+  set(CMAKE_DEPFILE_FLAGS_${lang} "--dep-file=<DEP_FILE>")
+  set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "--warning-as-errors")
+
+  string(APPEND CMAKE_${lang}_FLAGS_INIT " ")
+  string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -O0 -g")
+  string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -O2 -t4 -DNDEBUG")
+  string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -O2 -t2 -DNDEBUG")
+  string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -O2 -t2 -g -DNDEBUG")
+
+  set(CMAKE_${lang}_ARCHIVE_CREATE "\"${CMAKE_${lang}_COMPILER_AR}\" -r <TARGET> <OBJECTS>")
+  set(CMAKE_${lang}_ARCHIVE_APPEND "\"${CMAKE_${lang}_COMPILER_AR}\" -r <TARGET> <OBJECTS>")
+  set(CMAKE_${lang}_ARCHIVE_FINISH "")
+
+  set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -cs <SOURCE> -o <ASSEMBLY_SOURCE>")
+  set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -Ep <SOURCE> > <PREPROCESSED_SOURCE>")
+
+  set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}")
+  if(CMAKE_${lang}_COMPILER_ARG1)
+    separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}")
+    list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS})
+    unset(_COMPILER_ARGS)
+  endif()
+  list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-Ep" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
+
+endmacro()
-- 
cgit v0.12