# Compiler and linker
AS = as
CXX = g++
LD = g++
CPP = cpp
COUNT ?= 10
OVERFLOW_COUNT ?= 0
SAFE_COUNT ?= $(COUNT)

# Flags
ASFLAGS =
CXXFLAGS = -c -Wall
PREFIXES_CXXFLAGS ?= -O2 -static -Wall
LDFLAGS = 

# Target executable
TARGET = ubsan
TARGETI = ubsani
ARM_PREFIX_TARGET = arm_prefixes
UBSAN_HANDLER_IMPACT_TARGET = ubsan_handler_impact
UBSAN_HANDLER_IMPACT_ASM ?= ubsan_handler_impact.s
UBSAN_HANDLER_IMPACT_CPP ?= ubsan_handler_impact.cpp
UBSAN_HANDLER_IMPACT_STUB ?= ubsan_handler_stub.cpp

# Object files
OBJS = loop.o main.o
OBJSI = loopi.o main.o

# Default target
all: $(TARGET) $(TARGETI)

# Link object files to create executable
$(TARGET): $(OBJS)
	$(LD) $(LDFLAGS) -o $@ $^

$(TARGETI): $(OBJSI)
	$(LD) $(LDFLAGS) -o $@ $^

prefixes: prefixes.s prefixes.cpp
	$(CPP) -DCOUNT=$(COUNT) $< -o $<.i
	$(AS) $(ASFLAGS) -o prefixes.o $<.i
	$(CXX) $(PREFIXES_CXXFLAGS) -o prefixes prefixes.o prefixes.cpp

$(ARM_PREFIX_TARGET): arm_prefixes.s arm_prefixes.cpp
	$(CPP) -DCOUNT=$(COUNT) $< -o $<.i
	$(AS) $(ASFLAGS) -o arm_prefixes.o $<.i
	$(CXX) -Wall -o $(ARM_PREFIX_TARGET) arm_prefixes.o arm_prefixes.cpp

$(UBSAN_HANDLER_IMPACT_TARGET): $(UBSAN_HANDLER_IMPACT_ASM) $(UBSAN_HANDLER_IMPACT_CPP) $(UBSAN_HANDLER_IMPACT_STUB)
	$(CPP) -DCOUNT=$(COUNT) -DOVERFLOW_COUNT=$(OVERFLOW_COUNT) -DSAFE_COUNT=$(SAFE_COUNT) $(UBSAN_HANDLER_IMPACT_ASM) -o $(UBSAN_HANDLER_IMPACT_ASM).i
	$(AS) $(ASFLAGS) -o ubsan_handler_impact.o $(UBSAN_HANDLER_IMPACT_ASM).i
	$(CXX) -Wall -o $(UBSAN_HANDLER_IMPACT_TARGET) ubsan_handler_impact.o $(UBSAN_HANDLER_IMPACT_CPP) $(UBSAN_HANDLER_IMPACT_STUB)

# Compile assembly file
loop.o: loop.s
	$(CPP) -DCOUNT=$(COUNT) $< -o $<.i
	$(AS) $(ASFLAGS) -o $@ $<.i

loopi.o: loopi.s
	$(CPP) -DCOUNT=$(COUNT) $< -o $<.i
	$(AS) $(ASFLAGS) -o $@ $<.i

# Compile C++ file
main.o: main.cpp
	$(CXX) $(CXXFLAGS) -o $@ $<

# Clean up
clean:
	rm -f $(OBJS) $(TARGET) $(OBJSI) $(TARGETI) *.i prefixes.o prefixes arm_prefixes.o $(ARM_PREFIX_TARGET) ubsan_handler_impact.o $(UBSAN_HANDLER_IMPACT_TARGET)

# Phony targets
.PHONY: all clean prefixes $(ARM_PREFIX_TARGET) $(UBSAN_HANDLER_IMPACT_TARGET)
