Build: Add support for using target arch only

Add the ability to specify only target architecture without setting
target CPU. This commit adds support for GCC and ARMCLANG only.

For Armclang, set architecture is now checked against available arch
targets instead of processors. Modifiers (nodsp, nofp, nomve) is now
propagated to CMAKE_C_FLAGS in -march.

Use TFM_SYSTEM_ARCHITECTURE in CMakeListst.txt instead of previous
CMAKE_SYSTEM_ARCHITECTURE, which is not a CMAKE variable, to reduce
possible confusion with CMAKE_SYSTEM_ARCH which is a CMAKE variable
for Armclang.

Change-Id: If86e7ee82172374fb729f3e51ddfc411b7dd651e
Signed-off-by: Gabor Abonyi <gabor.abonyi@arm.com>
diff --git a/toolchain_ARMCLANG.cmake b/toolchain_ARMCLANG.cmake
index 68e320a..c0e6a5c 100644
--- a/toolchain_ARMCLANG.cmake
+++ b/toolchain_ARMCLANG.cmake
@@ -28,7 +28,6 @@
 
 macro(tfm_toolchain_reset_compiler_flags)
     set_property(DIRECTORY PROPERTY COMPILE_OPTIONS "")
-    string(REGEX REPLACE "\\+nodsp" ".no_dsp" CMAKE_ASM_CPU_FLAG "${CMAKE_SYSTEM_PROCESSOR}")
 
     add_compile_options(
         $<$<COMPILE_LANGUAGE:C>:-Wno-ignored-optimization-argument>
@@ -77,27 +76,77 @@
 endmacro()
 
 macro(tfm_toolchain_set_processor_arch)
-    set(CMAKE_SYSTEM_PROCESSOR       ${TFM_SYSTEM_PROCESSOR})
-    set(CMAKE_SYSTEM_ARCHITECTURE    ${TFM_SYSTEM_ARCHITECTURE})
+    if (DEFINED TFM_SYSTEM_PROCESSOR)
+        set(CMAKE_SYSTEM_PROCESSOR       ${TFM_SYSTEM_PROCESSOR})
+
+        if (DEFINED TFM_SYSTEM_MVE)
+            if(NOT TFM_SYSTEM_MVE)
+                string(APPEND CMAKE_SYSTEM_PROCESSOR "+nomve")
+            endif()
+        endif()
+
+        if (DEFINED TFM_SYSTEM_FP)
+            if(NOT TFM_SYSTEM_FP)
+                string(APPEND CMAKE_SYSTEM_PROCESSOR "+nofp")
+            endif()
+        endif()
+
+        if (DEFINED TFM_SYSTEM_DSP)
+            if(NOT TFM_SYSTEM_DSP)
+                string(APPEND CMAKE_SYSTEM_PROCESSOR "+nodsp")
+            endif()
+        endif()
+
+        string(REGEX REPLACE "\\+nodsp" ".no_dsp" CMAKE_ASM_CPU_FLAG "${CMAKE_SYSTEM_PROCESSOR}")
+    else()
+        set(CMAKE_ASM_CPU_FLAG  ${TFM_SYSTEM_ARCHITECTURE})
+
+        # Armasm uses different syntax than armclang for architecture targets
+        string(REGEX REPLACE "\\armv" "" CMAKE_ASM_CPU_FLAG "${CMAKE_ASM_CPU_FLAG}")
+        string(REGEX REPLACE "\\armv" "" CMAKE_ASM_CPU_FLAG "${CMAKE_ASM_CPU_FLAG}")
+
+        # Modifiers are additive instead of subtractive (.fp Vs .no_fp)
+        if (TFM_SYSTEM_DSP)
+            string(APPEND CMAKE_ASM_CPU_FLAG ".dsp")
+        else()
+            if (TFM_SYSTEM_MVE)
+                string(APPEND CMAKE_ASM_CPU_FLAG ".mve")
+            endif()
+
+            if (TFM_SYSTEM_FP)
+                string(APPEND CMAKE_ASM_CPU_FLAG ".fp")
+            endif()
+        endif()
+    endif()
+
+    # CMAKE_SYSTEM_ARCH is an ARMCLANG CMAKE internal variable, used to set
+    # compile and linker flags up until CMake 3.21 where CMP0123 was introduced:
+    # https://cmake.org/cmake/help/latest/policy/CMP0123.html
+    # This behavior is overwritten by setting CMAKE_C_FLAGS in
+    # tfm_toolchain_reload_compiler.
+    # Another use of this variable is to statisfy a requirement for ARMCLANG to
+    # set either the target CPU or the Architecture. This variable needs to be
+    # set to allow targeting architectures without a specific CPU.
+    set(CMAKE_SYSTEM_ARCH            ${TFM_SYSTEM_ARCHITECTURE})
 
     set(CMAKE_C_COMPILER_TARGET      arm-${CROSS_COMPILE})
     set(CMAKE_ASM_COMPILER_TARGET    arm-${CROSS_COMPILE})
 
     if (DEFINED TFM_SYSTEM_MVE)
         if(NOT TFM_SYSTEM_MVE)
-            string(APPEND CMAKE_SYSTEM_PROCESSOR "+nomve")
+            string(APPEND CMAKE_SYSTEM_ARCH "+nomve")
         endif()
     endif()
 
     if (DEFINED TFM_SYSTEM_FP)
         if(NOT TFM_SYSTEM_FP)
-            string(APPEND CMAKE_SYSTEM_PROCESSOR "+nofp")
+            string(APPEND CMAKE_SYSTEM_ARCH "+nofp")
         endif()
     endif()
 
     if (DEFINED TFM_SYSTEM_DSP)
         if(NOT TFM_SYSTEM_DSP)
-            string(APPEND CMAKE_SYSTEM_PROCESSOR "+nodsp")
+            string(APPEND CMAKE_SYSTEM_ARCH "+nodsp")
         endif()
     endif()
 
@@ -106,9 +155,9 @@
     # the ones we intend to use so that the validation will never fail.
     include(Compiler/ARMClang)
     set(CMAKE_C_COMPILER_PROCESSOR_LIST ${CMAKE_SYSTEM_PROCESSOR})
-    set(CMAKE_C_COMPILER_ARCH_LIST ${CMAKE_SYSTEM_PROCESSOR})
+    set(CMAKE_C_COMPILER_ARCH_LIST ${CMAKE_SYSTEM_ARCH})
     set(CMAKE_ASM_COMPILER_PROCESSOR_LIST ${CMAKE_SYSTEM_PROCESSOR})
-    set(CMAKE_ASM_COMPILER_ARCH_LIST ${CMAKE_SYSTEM_PROCESSOR})
+    set(CMAKE_ASM_COMPILER_ARCH_LIST ${CMAKE_SYSTEM_ARCH})
 endmacro()
 
 macro(tfm_toolchain_reload_compiler)
@@ -130,20 +179,22 @@
 
     # Cmake's armclang support will set either mcpu or march, but march gives
     # better code size so we manually set it.
-    set(CMAKE_C_FLAGS   "-march=${CMAKE_SYSTEM_ARCHITECTURE}")
+    set(CMAKE_C_FLAGS   "-march=${CMAKE_SYSTEM_ARCH}")
     set(CMAKE_ASM_FLAGS ${CMAKE_ASM_FLAGS_INIT})
 
-    set(CMAKE_C_LINK_FLAGS   "--cpu=${CMAKE_SYSTEM_PROCESSOR}")
-    set(CMAKE_ASM_LINK_FLAGS "--cpu=${CMAKE_SYSTEM_PROCESSOR}")
-    # But armlink doesn't support this +dsp syntax
-    string(REGEX REPLACE "\\+nodsp" "" CMAKE_C_LINK_FLAGS   "${CMAKE_C_LINK_FLAGS}")
-    string(REGEX REPLACE "\\+nodsp" "" CMAKE_ASM_LINK_FLAGS "${CMAKE_ASM_LINK_FLAGS}")
-    # And uses different syntax for +nofp
-    string(REGEX REPLACE "\\+nofp" ".no_fp" CMAKE_C_LINK_FLAGS   "${CMAKE_C_LINK_FLAGS}")
-    string(REGEX REPLACE "\\+nofp" ".no_fp" CMAKE_ASM_LINK_FLAGS "${CMAKE_ASM_LINK_FLAGS}")
+    if (DEFINED TFM_SYSTEM_PROCESSOR)
+        set(CMAKE_C_LINK_FLAGS   "--cpu=${CMAKE_SYSTEM_PROCESSOR}")
+        set(CMAKE_ASM_LINK_FLAGS "--cpu=${CMAKE_SYSTEM_PROCESSOR}")
+        # But armlink doesn't support this +dsp syntax
+        string(REGEX REPLACE "\\+nodsp" "" CMAKE_C_LINK_FLAGS   "${CMAKE_C_LINK_FLAGS}")
+        string(REGEX REPLACE "\\+nodsp" "" CMAKE_ASM_LINK_FLAGS "${CMAKE_ASM_LINK_FLAGS}")
+        # And uses different syntax for +nofp
+        string(REGEX REPLACE "\\+nofp" ".no_fp" CMAKE_C_LINK_FLAGS   "${CMAKE_C_LINK_FLAGS}")
+        string(REGEX REPLACE "\\+nofp" ".no_fp" CMAKE_ASM_LINK_FLAGS "${CMAKE_ASM_LINK_FLAGS}")
 
-    string(REGEX REPLACE "\\+nomve" ".no_mve" CMAKE_C_LINK_FLAGS   "${CMAKE_C_LINK_FLAGS}")
-    string(REGEX REPLACE "\\+nomve" ".no_mve" CMAKE_ASM_LINK_FLAGS "${CMAKE_ASM_LINK_FLAGS}")
+        string(REGEX REPLACE "\\+nomve" ".no_mve" CMAKE_C_LINK_FLAGS   "${CMAKE_C_LINK_FLAGS}")
+        string(REGEX REPLACE "\\+nomve" ".no_mve" CMAKE_ASM_LINK_FLAGS "${CMAKE_ASM_LINK_FLAGS}")
+    endif()
 
     # Workaround for issues with --depend-single-line with armasm and Ninja
     if (CMAKE_GENERATOR STREQUAL "Ninja")