# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

cmake_minimum_required(VERSION 3.13.4)

#-------------------------------------------------------------------------------
# Project configuration
#-------------------------------------------------------------------------------

project(iree-riscv32)

set_property(GLOBAL PROPERTY USE_FOLDERS ON)

list(APPEND CMAKE_MODULE_PATH
  ${CMAKE_CURRENT_LIST_DIR}/cmake/
)

set(IREE_SOURCE_DIR "$ENV{ROOTDIR}/toolchain/iree" CACHE PATH
    "IREE source code path. (default: $ENV{ROOTDIR}/toolchain/iree)")

include_directories(BEFORE SYSTEM ${CMAKE_CURRENT_LIST_DIR})
include_directories(BEFORE SYSTEM ${CMAKE_CURRENT_BINARY_DIR})

#-------------------------------------------------------------------------------
# Sparrow-specific settings
#-------------------------------------------------------------------------------
set(TCM_LENGTH "16M" CACHE STRING "TCM Length (default: 16M)")
add_link_options("LINKER:--defsym=__tcm_length__=${TCM_LENGTH}")
set(STACK_SIZE "10K" CACHE STRING "Stack size (default: 10K)")
add_link_options("LINKER:--defsym=__stack_size__=${STACK_SIZE}")
set(BUILD_WITH_NATIVE OFF CACHE BOOL "Build the target with native support (default: OFF)")
set(BUILD_WITH_KELVIN OFF CACHE BOOL "Build the target with kelvin BSP (default: OFF)")
set(BUILD_WITH_RVV ON CACHE BOOL "Build the target with RVV (default: ON)")
set(BUILD_NO_WMMU OFF CACHE BOOL "Build targets with no WMMU (default: OFF)")
set(PRINT_IREE_STATS ON CACHE BOOL "Print out information on IREE statistics (default: ON)")

#-------------------------------------------------------------------------------
# IREE-specific settings
#-------------------------------------------------------------------------------
set(IREE_BUILD_COMPILER OFF)
set(IREE_ENABLE_MLIR OFF)
set(IREE_BUILD_SAMPLES OFF)
set(IREE_ENABLE_THREADING OFF)
set(IREE_BUILD_TESTS OFF)
set(IREE_BUILD_BINDINGS_TFLITE OFF)
set(IREE_HAL_DRIVER_LOCAL_SYNC ON CACHE BOOL "" FORCE)
set(IREE_HAL_EXECUTABLE_LOADER_DEFAULTS OFF CACHE BOOL "" FORCE)
set(IREE_HAL_EXECUTABLE_LOADER_VMVX_MODULE ON CACHE BOOL "" FORCE)
set(IREE_HAL_EXECUTABLE_PLUGIN_DEFAULTS OFF CACHE BOOL "" FORCE)
set(IREE_HAL_EXECUTABLE_PLUGIN_EMBEDDED_ELF ON CACHE BOOL "" FORCE)
set(IREE_HAL_DRIVER_DEFAULTS OFF CACHE BOOL "" FORCE)

#-------------------------------------------------------------------------------
# IREE-specific definitions
#-------------------------------------------------------------------------------
set(SPARROW_CONFIG_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/sparrow_config.h")
add_compile_definitions(FLATCC_USE_GENERIC_ALIGNED_ALLOC)
add_compile_definitions(IREE_SYNCHRONIZATION_DISABLE_UNSAFE=1)
add_compile_definitions(IREE_FILE_IO_ENABLE=0)
add_compile_definitions(IREE_USER_CONFIG_H="${SPARROW_CONFIG_HEADER}")
if (NOT PRINT_IREE_STATS)
  add_compile_definitions(IREE_HAL_COMMAND_BUFFER_VALIDATION_ENABLE=0)
  add_compile_definitions(IREE_HAL_MODULE_STRING_UTIL_ENABLE=0)
  add_compile_definitions(IREE_STATISTICS_ENABLE=0)
  add_compile_definitions(IREE_STATUS_MODE=0)
  add_compile_definitions(IREE_VM_BACKTRACE_ENABLE=0)
  add_compile_definitions(IREE_VM_EXT_F64_ENABLE=0)
  add_compile_definitions(IREE_VM_EXT_I64_ENABLE=0)
endif()

# The project does a cmake hack here -- at the executable linkage stage, we
# append the logging library (and springbok BSP). Any logging library update
# (libspringbok.a or libnative_log.a) only gets rebuilt during executable
# linkage, but not during library compilation.
#
# However, an explicit include path gets added here across all targets so the
# header files can be found during compilation.
if(BUILD_WITH_NATIVE)
  # Add the native printout support.
  add_subdirectory(native_log)
  include(riscv_native_log)
  include_directories(native_log)
elseif(NOT BUILD_WITH_KELVIN)
  # Springbok BSP-related setting
  set(SPRINGBOK_LINKER_SCRIPT "$ENV{ROOTDIR}/sw/vec/springbok/springbok.ld" CACHE PATH "Springbok linker script path (default: springbok.ld)")
  add_subdirectory($ENV{ROOTDIR}/sw/vec/springbok springbok)
  include(riscv_springbok)
  include_directories($ENV{ROOTDIR}/sw/vec/springbok/include)
else()
  # Kelvin BSP-related setting
  set(KELVIN_LINKER_SCRIPT "$ENV{ROOTDIR}/sw/kelvin/crt/kelvin.ld" CACHE PATH "Kelvin linker script path (default: kelvin.ld)")
  add_subdirectory($ENV{ROOTDIR}/sw/kelvin/crt kelvin)
  include(riscv_kelvin)
  include_directories($ENV{ROOTDIR}/sw/kelvin)
  include_directories($ENV{ROOTDIR}/sw/kelvin/crt)
endif()

message(STATUS "Include IREE source at ${IREE_SOURCE_DIR}")
# Build IREE runtime libraries.
add_subdirectory(${IREE_SOURCE_DIR} iree)

# Apply IREE's CMake variables and build options so we can use IREE build
# functions properly in this project.
set(IREE_ROOT_DIR "${IREE_SOURCE_DIR}" CACHE PATH "IREE Root directory")
include(sparrow_ops)

include(sparrow_static_module)
include(sparrow_vmvx_module)
include(sparrow_modules)
include(iree_model_input)
include(sparrow_test)

# softmax op (and mfcc) requires floorf implementation in libm. Use the nano
# version.
if(NOT BUILD_WITH_KELVIN)
  find_library(m m
  PATHS
    "${RISCV_TOOLCHAIN_ROOT}/riscv32-unknown-elf/lib/newlib-nano/"
  REQUIRED)
else()
  find_library(m m_nano
  PATHS
    "${RISCV_TOOLCHAIN_ROOT}/riscv32-unknown-elf/lib"
  REQUIRED)
endif()
link_libraries(m)

# Add the included directory here.
add_subdirectory(audio_prep)
add_subdirectory(device)
add_subdirectory(model_util)
add_subdirectory(risp4ml)

add_subdirectory(samples)
add_subdirectory(ssd_postprocess)
add_subdirectory(ukernel)

# Add pigweed support
include($ENV{ROOTDIR}/sw/pigweed/pw_build/pigweed.cmake)
pw_set_backend(pw_log pw_log_basic)
pw_set_backend(pw_assert pw_assert_log)
pw_set_backend(pw_sys_io pw_sys_io_stdio)
add_subdirectory($ENV{ROOTDIR}/sw/pigweed pw)
