SHELL := /bin/bash
#
# Set debug=yes for compiling code with -O0
#
ifeq ($(debug),)
 debug := no
endif
ifeq ($(filter $(debug),yes no),)
 $(error Invalid value '$(debug)' in 'debug=$(debug)', use 'yes' or 'no')
endif
$(info debug=$(debug))
#
# Set debug_lib_x86sim=yes for linking against lnx64.g/libx86sim.so
#
ifeq ($(debug_lib_x86sim),)
 debug_lib_x86sim := no
endif
ifeq ($(filter $(debug_lib_x86sim),yes no),)
 $(error Invalid value '$(debug_lib_x86sim)' in 'debug_lib_x86sim=$(debug_lib_x86sim)', use 'yes' or 'no')
endif
$(info debug_lib_x86sim=$(debug_lib_x86sim))
#
# Set address_sanitizer=yes to detect out of bound memory access in kernel code
# Set ASAN_SYMBOLIZER_PATH=${XILINX_VITIS_AIETOOLS}/lnx64.o/tools/clang/bin/llvm-symbolizer
# to get a better stack trace.
#
ifeq ($(address_sanitizer),)
 address_sanitizer := no
endif
ifeq ($(filter $(address_sanitizer),yes no),)
 $(error Invalid value '$(address_sanitizer)' in 'address_sanitizer=$(address_sanitizer)', use 'yes' or 'no')
endif
$(info address_sanitizer=$(address_sanitizer))
#
# Set verbose=1 to print extra output in x86simopt passes to stderr.
#
ifeq ($(verbose),)
  verbose := 0
endif

KERNEL_FIXUP_OPTS := --thread-local-globals=1
KERNEL_FIXUP_OPTS += --align-globals=1
KERNEL_FIXUP_OPTS += --internalize-global-vars=1
KERNEL_FIXUP_OPTS += --internalize-funcs=1
KERNEL_FIXUP_OPTS += --truncate-vector-load-store-addresses=1 --max-required-vector-alignment=16

GRAPH_FIXUP_OPTS  := --thread-local-globals=0
GRAPH_FIXUP_OPTS  += --internalize-global-vars=0
GRAPH_FIXUP_OPTS  += --internalize-funcs=0
GRAPH_FIXUP_OPTS  += --align-globals=0 --max-required-vector-alignment=16
GRAPH_FIXUP_OPTS  += --define-undefined-luts=0 --define-kernel-stubs=1

#
# set clang_static_analyzer=yes to enable kernel analysis using clang analyzer
#
ifeq ($(clang_static_analyzer),)
 clang_static_analyzer := no
endif
ifeq ($(filter $(clang_static_analyzer),yes no),)
 $(error Invalid value '$(clang_static_analyzer)' in 'clang_static_analyzer=$(clang_static_analyzer)', use 'yes' or 'no')
endif
$(info clang_static_analyzer=$(clang_static_analyzer))

ifeq ($(clang_static_analyzer),yes)
 KERNEL_ANALYSIS := kernelAnalysis
endif

#
# use clang_static_analyzer_args to pass custom arguments to clang static analyzer
#
ANALYZER_FLAGS = --analyze -Xanalyzer -analyzer-output=html -o kernel_analysis_html_reports/$< \
-Xclang -analyzer-disable-checker=deadcode.DeadStores 
ifneq ($(clang_static_analyzer_args),)
    ANALYZER_FLAGS += $(clang_static_analyzer_args) 
    $(info clang_static_analyzer_args=$(clang_static_analyzer_args))
endif

#
ifeq ($(XILINX_VITIS_AIETOOLS),)
XILINX_VITIS_AIETOOLS:=${XILINX_VITIS}/aietools
endif

LLVM_OPT    := $(XILINX_VITIS_AIETOOLS)/lnx64.o/tools/clang/bin/opt
X86SIMOPT   := $(XILINX_VITIS_AIETOOLS)/lib/lnx64.o/libLLVMX86SimOpt.so
CLANG       := $(XILINX_VITIS_AIETOOLS)/lnx64.o/tools/clang/bin/clang
AIE_CLANGPP := $(XILINX_VITIS_AIETOOLS)/bin/aie_clang++
GPP         := $(XILINX_VITIS_AIETOOLS)/tps/lnx64/gcc/bin/g++
LD          := $(XILINX_VITIS_AIETOOLS)/tps/lnx64/gcc/bin/ld

ifeq ($(XILINX_VITIS_AIETOOLS),)
XILINX_VITIS_AIETOOLS:=${XILINX_VITIS}/aietools
endif

ifeq ($(address_sanitizer),yes)
 ASAN_CFLAGS := -fsanitize=address
 ASAN_LFLAGS := -L${XILINX_VITIS_AIETOOLS}/lnx64.o/tools/clang/lib/clang/18/lib/linux/ -lclang_rt.asan-x86_64
 ASAN_SUPPORT_FLAGS := -ldl 
endif

CFLAGS := -g 
CFLAGS += -D__X86SIM__ -D__PTHREAD_API__
CFLAGS += -fvisibility=hidden
ifeq ($(debug),yes)
  CFLAGS +=  -O0
endif
CFLAGS += -D__AIE_ARCH__=10 
CFLAGS += -D__LOCK_FENCE_MODE__=0
CFLAGS += -DAIE_OPTION_SCALAR_FLOAT_ON_VECTOR

CFLAGS += -I ../..
CFLAGS += -I ${XILINX_VITIS_AIETOOLS}/include
CFLAGS += -I ${XILINX_VITIS_AIETOOLS}/data/osci_systemc/include
CFLAGS += -I ${XILINX_VITIS_AIETOOLS}/tps/boost_1_72_0
CFLAGS += -I /home/amd/training/system_simulation/lab/sys_project/aie_component/build/x86sim/../..
CFLAGS += -I /home/amd/training/system_simulation/lab/sys_project/aie_component/build/x86sim/../../AIE/kernels
CFLAGS += -I /home/amd/training/system_simulation/lab/sys_project/aie_component/build/x86sim/../../AIE

CFLAGS += -I ${XILINX_VITIS_AIETOOLS}/data/versal_prod/lib/runtime_cxx/libcxx-lite/include
GPP_CFLAGS := $(CFLAGS) -std=c++17
AIE_CFLAGS := $(CFLAGS) -D_X86SIM_LIBCPP_16 -D__AIENGINE__ -D__AIE_ARCH__=10
AIE_CFLAGS += -std=c++2a -stdlib=libc++ -gdwarf-4

CLANG_CFLAGS := $(CFLAGS)

CLANG_CFLAGS += -I/opt/amd/2025.1/Vitis/aietools/include -I/opt/amd/2025.1/Vitis/aietools/tps/lnx64/gcc/include/c++/8.3.0 -I/opt/amd/2025.1/Vitis/aietools/tps/lnx64/gcc/include/c++/8.3.0/x86_64-pc-linux-gnu -I/opt/amd/2025.1/Vitis/aietools/tps/lnx64/gcc/include 
CLANG_CFLAGS += -Wno-error=reserved-user-defined-literal 
CLANG_CFLAGS += -std=c++17
CLANG_CFLAGS += -gdwarf-4

ifeq ($(debug_lib_x86sim),yes)
EXT_LIB_X86SIM := g
else
EXT_LIB_X86SIM := o
endif
LFLAGS := -lx86simStreamApiAIE10 -lx86sim -Wl,-R${XILINX_VITIS_AIETOOLS}/lib/lnx64.$(EXT_LIB_X86SIM)
LFLAGS += -Wl,-R${XILINX_VITIS_AIETOOLS}/tps/lnx64/gcc/lib64

DEPFLAGS = -MT $@ -MMD -MP -MF $(<F).Td
POSTCOMPILE = @mv -f $(<F).Td $(<F).d && touch $@

all:	${KERNEL_ANALYSIS} sim.out libsim.so libxmcsim.so 
vmc:	libxmcsim.so wrap_graph.cpp.d


wrap_graph.cpp.d:	 wrap_graph.cpp
	$(CLANG) -S -emit-llvm -fPIC -E -MT -M -MM -MP -MF $(<F).d $(CLANG_CFLAGS) wrap_graph.cpp

wrap_graph.cpp.ll:	 wrap_graph.cpp wrap_graph.cpp.d
	$(CLANG) -S -emit-llvm -fPIC -c -o wrap_graph.cpp.ll $(CLANG_CFLAGS) $(DEPFLAGS) $(ASAN_CFLAGS) wrap_graph.cpp
	$(POSTCOMPILE)

wrap_graph.cpp.opt.ll:	 wrap_graph.cpp.ll
	set -o pipefail; \
export XILINX_VITIS_AIETOOLS_X86SIM_OPT_OPTIONS="$(GRAPH_FIXUP_OPTS)"; $(LLVM_OPT) -S -load-pass-plugin=$(X86SIMOPT) -passes=x86simopt --x86simopt-log wrap_graph.cpp.opt.ll.log --verbose=$(verbose) $< -o $@ 2> >(tee -a wrap_graph.cpp.opt.ll.log >&2)

wrap_graph.cpp.o:	 wrap_graph.cpp.opt.ll 
	$(CLANG) -O1 -fpic -fvisibility=hidden -c -o $@  $<

PthreadSim.cpp.o: PthreadSim.cpp PthreadSim.cpp.d
	g++ -fPIC -c -o PthreadSim.cpp.o $(DEPFLAGS) $(GPP_CFLAGS) PthreadSim.cpp
	$(POSTCOMPILE)

PthreadSimBasic.cpp.o: PthreadSimBasic.cpp PthreadSimBasic.cpp.d
	g++ -fPIC -c -o PthreadSimBasic.cpp.o $(DEPFLAGS) $(GPP_CFLAGS) PthreadSimBasic.cpp
	$(POSTCOMPILE)

PthreadSimSwemu.cpp.o: PthreadSimSwemu.cpp PthreadSimSwemu.cpp.d
	g++ -fPIC -c -o PthreadSimSwemu.cpp.o -I ${XILINX_HLS}/include $(DEPFLAGS) $(GPP_CFLAGS) PthreadSimSwemu.cpp
	$(POSTCOMPILE)

PthreadSimXmc.cpp.o: PthreadSimXmc.cpp PthreadSimXmc.cpp.d
	g++ -fPIC -c -o PthreadSimXmc.cpp.o $(DEPFLAGS) $(GPP_CFLAGS) PthreadSimXmc.cpp
	$(POSTCOMPILE)


wrap_hb27_2i.cc.ll:	 wrap_hb27_2i.cc wrap_hb27_2i.cc.d
	$(AIE_CLANGPP) -S -emit-llvm -fPIC -c -o wrap_hb27_2i.cc.ll $(AIE_CFLAGS) \
$(DEPFLAGS) $(ASAN_CFLAGS) $(MY_KERNEL_CFLAGS) wrap_hb27_2i.cc
	$(POSTCOMPILE)

wrap_hb27_2i.cc.opt.ll:	 wrap_hb27_2i.cc.ll
	set -o pipefail; \
export XILINX_VITIS_AIETOOLS_X86SIM_OPT_OPTIONS="$(KERNEL_FIXUP_OPTS)"; $(LLVM_OPT) -S -load-pass-plugin=$(X86SIMOPT) -passes=x86simopt --x86simopt-log $@.log --verbose=$(verbose) $< -o $@ 2> >(tee -a $@.log >&2)

wrap_hb27_2i.cc.o:	 wrap_hb27_2i.cc.opt.ll 
	$(CLANG) -fpic -fvisibility=hidden -c -o $@  $<

wrap_hb27_2i.cc.analysis:	 wrap_hb27_2i.cc 
	$(AIE_CLANGPP) -fPIC $(ANALYZER_FLAGS) -c $(AIE_CFLAGS) wrap_hb27_2i.cc 2>&1 | tee Kernel_analysis_report.log -a


wrap_polar_clip.cpp.ll:	 wrap_polar_clip.cpp wrap_polar_clip.cpp.d
	$(AIE_CLANGPP) -S -emit-llvm -fPIC -c -o wrap_polar_clip.cpp.ll $(AIE_CFLAGS) \
$(DEPFLAGS) $(ASAN_CFLAGS) $(MY_KERNEL_CFLAGS) wrap_polar_clip.cpp
	$(POSTCOMPILE)

wrap_polar_clip.cpp.opt.ll:	 wrap_polar_clip.cpp.ll
	set -o pipefail; \
export XILINX_VITIS_AIETOOLS_X86SIM_OPT_OPTIONS="$(KERNEL_FIXUP_OPTS)"; $(LLVM_OPT) -S -load-pass-plugin=$(X86SIMOPT) -passes=x86simopt --x86simopt-log $@.log --verbose=$(verbose) $< -o $@ 2> >(tee -a $@.log >&2)

wrap_polar_clip.cpp.o:	 wrap_polar_clip.cpp.opt.ll 
	$(CLANG) -fpic -fvisibility=hidden -c -o $@  $<

wrap_polar_clip.cpp.analysis:	 wrap_polar_clip.cpp 
	$(AIE_CLANGPP) -fPIC $(ANALYZER_FLAGS) -c $(AIE_CFLAGS) wrap_polar_clip.cpp 2>&1 | tee Kernel_analysis_report.log -a


wrap_classify.cc.ll:	 wrap_classify.cc wrap_classify.cc.d
	$(AIE_CLANGPP) -S -emit-llvm -fPIC -c -o wrap_classify.cc.ll $(AIE_CFLAGS) \
$(DEPFLAGS) $(ASAN_CFLAGS) $(MY_KERNEL_CFLAGS) wrap_classify.cc
	$(POSTCOMPILE)

wrap_classify.cc.opt.ll:	 wrap_classify.cc.ll
	set -o pipefail; \
export XILINX_VITIS_AIETOOLS_X86SIM_OPT_OPTIONS="$(KERNEL_FIXUP_OPTS)"; $(LLVM_OPT) -S -load-pass-plugin=$(X86SIMOPT) -passes=x86simopt --x86simopt-log $@.log --verbose=$(verbose) $< -o $@ 2> >(tee -a $@.log >&2)

wrap_classify.cc.o:	 wrap_classify.cc.opt.ll 
	$(CLANG) -fpic -fvisibility=hidden -c -o $@  $<

wrap_classify.cc.analysis:	 wrap_classify.cc 
	$(AIE_CLANGPP) -fPIC $(ANALYZER_FLAGS) -c $(AIE_CFLAGS) wrap_classify.cc 2>&1 | tee Kernel_analysis_report.log -a

aie_kernels_obj.o: wrap_hb27_2i.cc.o wrap_polar_clip.cpp.o wrap_classify.cc.o
	$(LD) -o aie_kernels_obj.o -r wrap_hb27_2i.cc.o wrap_polar_clip.cpp.o wrap_classify.cc.o -L${XILINX_VITIS_AIETOOLS}/lib/lnx64.o -lc++ -lc++abi ${ASAN_LFLAGS} ${MY_KERNEL_LFLAGS}

cleanKernelAnalysisReports:
	rm -rf Kernel_analysis_report.log kernel_analysis_html_reports

kernelAnalysis:	cleanKernelAnalysisReports	wrap_hb27_2i.cc.analysis	wrap_polar_clip.cpp.analysis	wrap_classify.cc.analysis	

sim.out: aie_kernels_obj.o  PthreadSimBasic.cpp.o PthreadSim.cpp.o wrap_graph.cpp.o
	aie_g++ -o sim.out -D__AIE_ARCH__=10 aie_kernels_obj.o  PthreadSimBasic.cpp.o PthreadSim.cpp.o wrap_graph.cpp.o -lpthread -ladf_api_x86sim -lx86simSocketUtil ${LFLAGS} ${ASAN_SUPPORT_FLAGS}

libsim.so: aie_kernels_obj.o  PthreadSimSwemu.cpp.o PthreadSim.cpp.o
	aie_g++ -shared -o libsim.so -D__AIE_ARCH__=10 aie_kernels_obj.o  PthreadSimSwemu.cpp.o PthreadSim.cpp.o -lc++ -lpthread -ladf_api_x86sim -lx86simDummySocketUtil ${LFLAGS} ${ASAN_SUPPORT_FLAGS}

libxmcsim.so: aie_kernels_obj.o  PthreadSimXmc.cpp.o PthreadSim.cpp.o
	aie_g++ -shared -o libxmcsim.so -D__AIE_ARCH__=10 aie_kernels_obj.o  PthreadSimXmc.cpp.o PthreadSim.cpp.o -lc++ -lpthread -ladf_api_x86sim -lx86simDummySocketUtil ${LFLAGS} ${ASAN_SUPPORT_FLAGS}

clean: 
	rm -f  wrap_hb27_2i.cc.o wrap_polar_clip.cpp.o wrap_classify.cc.o wrap_graph.cpp.ll wrap_graph.cpp.opt.ll wrap_hb27_2i.cc.ll wrap_hb27_2i.cc.opt.ll wrap_polar_clip.cpp.ll wrap_polar_clip.cpp.opt.ll wrap_classify.cc.ll wrap_classify.cc.opt.ll aie_kernels_obj.o PthreadSim.cpp.o PthreadSimBasic.cpp.o PthreadSimSwemu.cpp.o wrap_graph.cpp.o sim.out  libsim.so

%.d: ;
.PRECIOUS: %.d

include  $(wildcard wrap_graph.cpp.d) $(wildcard PthreadSim.cpp.d) $(wildcard PthreadSimBasic.cpp.d) $(wildcard PthreadSimSwemu.cpp.d) $(wildcard PthreadSimXmc.cpp.d) $(wildcard wrap_hb27_2i.cc.d) $(wildcard wrap_polar_clip.cpp.d) $(wildcard wrap_classify.cc.d)
