march.mk 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #
  2. # Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  3. #
  4. # SPDX-License-Identifier: BSD-3-Clause
  5. #
  6. # This build helper makefile is used to determine a suitable march build
  7. # option to be used, based on platform provided ARM_ARCH_MAJOR/MINOR
  8. # data and compiler supported march version.
  9. # Set the compiler's target architecture profile based on
  10. # ARM_ARCH_MAJOR and ARM_ARCH_MINOR options.
  11. # This is used to collect available march values from compiler.
  12. # Example on a gcc-12.2 arm64 toolchain it will look like:
  13. # [...]
  14. #./aarch64-none-elf-gcc --target-help -march=foo
  15. # cc1: error: unknown value 'foo' for '-march'
  16. # cc1: note: valid arguments are: armv8-a armv8.1-a armv8.2-a armv8.3-a armv8.4-a armv8.5-a
  17. # armv8.6-a armv8.7-a armv8.8-a armv8-r armv9-a
  18. # [...]
  19. #
  20. GCC_MARCH_OUTPUT := $(if $($(ARCH)-cc),$(shell $($(ARCH)-cc) -march=foo -Q --help=target -v 2>&1))
  21. # This function is used to find the best march value supported by the given compiler.
  22. # We try to use `GCC_MARCH_OUTPUT` which has verbose message with supported march values we filter that
  23. # to find armvX.Y-a or armvX-a values, then filter the best supported arch based on ARM_ARCH_MAJOR.
  24. #
  25. # Example on a gcc-12.2 arm64 toolchain this will return armv9-a if platform requested for armv9.2-a
  26. # Similarly on gcc 11.3 it would return armv8.6-a if platform requested armv8.8-a
  27. define major_best_avail_march
  28. $(1) := $(lastword $(filter armv$(ARM_ARCH_MAJOR)% ,$(filter armv%-a, $(GCC_MARCH_OUTPUT))))
  29. endef
  30. # This function is used to just return latest march value supported by the given compiler.
  31. #
  32. # Example: this would return armv8.6-a on a gcc-11.3 when platform requested for armv9.0-a
  33. #
  34. # Thus this function should be used in conjunction with major_best_avail_march, when best match
  35. # is not found it should be ok to try with lastest known supported march value from the
  36. # compiler.
  37. define latest_match_march
  38. $(1) := $(lastword $(filter armv%-a, $(GCC_MARCH_OUTPUT)))
  39. endef
  40. ifdef MARCH_DIRECTIVE
  41. march-directive := $(MARCH_DIRECTIVE)
  42. else
  43. ifeq (${ARM_ARCH_MINOR},0)
  44. provided-march = armv${ARM_ARCH_MAJOR}-a
  45. else
  46. provided-march = armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a
  47. endif
  48. ifeq ($(filter %-clang,$($(ARCH)-cc-id)),)
  49. # We expect from Platform to provide a correct Major/Minor value but expecting something
  50. # from compiler with unsupported march means we shouldn't fail without trying anything,
  51. # so here we try to find best supported march value and use that for compilation.
  52. # If we don't support current march version from gcc compiler, try with lower arch based on
  53. # availability. In TF-A there is no hard rule for need of higher version march for basic
  54. # functionality, denying a build on only this fact doesn't look correct, so try with best
  55. # or latest march values from whats available from compiler.
  56. ifeq (,$(findstring $(provided-march), $(GCC_MARCH_OUTPUT)))
  57. $(eval $(call major_best_avail_march, available-march))
  58. ifeq (, $(available-march))
  59. $(eval $(call latest_match_march, available-march))
  60. endif
  61. # If we fail to come up with any available-march value so far, don't update
  62. # provided-march and thus allow the build to fail using the provided-march
  63. # which is derived based on arch_major and arch_minor values.
  64. ifneq (,$(available-march))
  65. provided-march := ${available-march}
  66. endif
  67. endif # provided-march supported
  68. endif # not clang
  69. march-directive := -march=${provided-march}
  70. # Set the compiler's architecture feature modifiers
  71. ifneq ($(arch-features), none)
  72. # Strip "none+" from arch-features
  73. arch-features := $(subst none+,,$(arch-features))
  74. march-directive := $(march-directive)+$(arch-features)
  75. # Print features
  76. $(info Arm Architecture Features specified: $(subst +, ,$(arch-features)))
  77. endif #(arch-features)
  78. endif # MARCH_DIRECTIVE