97 lines
3.6 KiB
CMake
97 lines
3.6 KiB
CMake
# cmake/ppc_test_pipeline.cmake
|
|
# PPC assembly test build pipeline
|
|
# Provides ppc_add_test_binary() for assembling, linking, and generating
|
|
# symbol maps from PPC assembly test files.
|
|
|
|
# Locate PPC toolchain in tools/ directory
|
|
set(PPC_TOOLS_DIR "${PROJECT_SOURCE_DIR}/tools/binutils")
|
|
|
|
if(WIN32)
|
|
set(PPC_ASSEMBLER "${PPC_TOOLS_DIR}/powerpc-none-elf-as.exe")
|
|
set(PPC_LINKER "${PPC_TOOLS_DIR}/powerpc-none-elf-ld.exe")
|
|
set(PPC_NM "${PPC_TOOLS_DIR}/powerpc-none-elf-nm.exe")
|
|
else()
|
|
set(PPC_ASSEMBLER "${PPC_TOOLS_DIR}/powerpc-none-elf-as")
|
|
set(PPC_LINKER "${PPC_TOOLS_DIR}/powerpc-none-elf-ld")
|
|
set(PPC_NM "${PPC_TOOLS_DIR}/powerpc-none-elf-nm")
|
|
endif()
|
|
|
|
# Verify toolchain exists
|
|
if(NOT EXISTS "${PPC_ASSEMBLER}")
|
|
message(FATAL_ERROR "PPC assembler not found at ${PPC_ASSEMBLER}")
|
|
endif()
|
|
if(NOT EXISTS "${PPC_LINKER}")
|
|
message(FATAL_ERROR "PPC linker not found at ${PPC_LINKER}")
|
|
endif()
|
|
|
|
message(STATUS "PowerPC assembler: ${PPC_ASSEMBLER}")
|
|
message(STATUS "PowerPC linker: ${PPC_LINKER}")
|
|
|
|
# Convert Windows paths to Cygwin paths for binutils (Windows only)
|
|
function(_ppc_convert_to_cygwin_path WINDOWS_PATH OUTPUT_VAR)
|
|
if(WIN32 AND WINDOWS_PATH MATCHES "^([A-Za-z]):")
|
|
string(REGEX REPLACE "^([A-Za-z]):" "/cygdrive/\\1" CYGWIN_PATH "${WINDOWS_PATH}")
|
|
string(SUBSTRING "${CYGWIN_PATH}" 10 1 DRIVE_LETTER)
|
|
string(TOLOWER "${DRIVE_LETTER}" DRIVE_LOWER)
|
|
string(REGEX REPLACE "^/cygdrive/[A-Za-z]" "/cygdrive/${DRIVE_LOWER}" CYGWIN_PATH "${CYGWIN_PATH}")
|
|
string(REPLACE "\\" "/" CYGWIN_PATH "${CYGWIN_PATH}")
|
|
set(${OUTPUT_VAR} "${CYGWIN_PATH}" PARENT_SCOPE)
|
|
else()
|
|
set(${OUTPUT_VAR} "${WINDOWS_PATH}" PARENT_SCOPE)
|
|
endif()
|
|
endfunction()
|
|
|
|
# Add a PPC test binary from an assembly file.
|
|
# Assembles .s -> .o, links .o -> .bin, generates .o -> .map.
|
|
# Appends output files to PPC_TEST_BINS, PPC_TEST_MAPS, PPC_TEST_OBJS
|
|
# global properties.
|
|
function(ppc_add_test_binary ASM_FILE OBJ_DIR BIN_DIR)
|
|
get_filename_component(BASE_NAME ${ASM_FILE} NAME_WE)
|
|
|
|
set(OBJ_FILE ${OBJ_DIR}/${BASE_NAME}.o)
|
|
set(BIN_FILE ${BIN_DIR}/${BASE_NAME}.bin)
|
|
set(MAP_FILE ${BIN_DIR}/${BASE_NAME}.map)
|
|
|
|
_ppc_convert_to_cygwin_path("${OBJ_FILE}" OBJ_FILE_CYGWIN)
|
|
_ppc_convert_to_cygwin_path("${BIN_FILE}" BIN_FILE_CYGWIN)
|
|
_ppc_convert_to_cygwin_path("${MAP_FILE}" MAP_FILE_CYGWIN)
|
|
_ppc_convert_to_cygwin_path("${ASM_FILE}" ASM_FILE_CYGWIN)
|
|
|
|
# Assemble .s to .o
|
|
add_custom_command(
|
|
OUTPUT ${OBJ_FILE}
|
|
COMMAND ${PPC_ASSEMBLER}
|
|
-a32 -be -mregnames -mpower7 -maltivec -mvsx -mvmx128 -R
|
|
-o ${OBJ_FILE_CYGWIN}
|
|
${ASM_FILE_CYGWIN}
|
|
DEPENDS ${ASM_FILE}
|
|
COMMENT "Assembling ${BASE_NAME}.s"
|
|
VERBATIM
|
|
)
|
|
|
|
# Link .o to .bin
|
|
add_custom_command(
|
|
OUTPUT ${BIN_FILE}
|
|
COMMAND ${PPC_LINKER}
|
|
-A powerpc:common32 -melf32ppc -EB -nostdlib
|
|
--oformat=binary -Ttext=0x82010000 -e 0x82010000
|
|
-o ${BIN_FILE_CYGWIN}
|
|
${OBJ_FILE_CYGWIN}
|
|
DEPENDS ${OBJ_FILE}
|
|
COMMENT "Linking ${BASE_NAME}.bin"
|
|
VERBATIM
|
|
)
|
|
|
|
# Generate symbol map
|
|
add_custom_command(
|
|
OUTPUT ${MAP_FILE}
|
|
COMMAND ${PPC_NM} --numeric-sort ${OBJ_FILE_CYGWIN} > ${MAP_FILE}
|
|
DEPENDS ${OBJ_FILE}
|
|
COMMENT "Generating symbol map for ${BASE_NAME}"
|
|
VERBATIM
|
|
)
|
|
|
|
set_property(GLOBAL APPEND PROPERTY PPC_TEST_BINS ${BIN_FILE})
|
|
set_property(GLOBAL APPEND PROPERTY PPC_TEST_MAPS ${MAP_FILE})
|
|
set_property(GLOBAL APPEND PROPERTY PPC_TEST_OBJS ${OBJ_FILE})
|
|
endfunction()
|