CFLAGS?=-std=c11 -O2 -g -fno-common -Wall -Wno-switch
.DEFAULT_GOAL := pcfc11

SRCS=$(wildcard *.c)
OBJS=$(SRCS:.c=.o)

TEST_SRCS=$(wildcard test/*.c)
TESTS=$(TEST_SRCS:.c=.exe)

# Legacy common-symbol test explicitly requests its intended linkage policy.
test/commonsym.exe: override PCFCFLAGS += -fcommon
stage2/test/commonsym.exe: override PCFCFLAGS += -fcommon

# Stage 1

pcfc11: $(OBJS)
	$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)

$(OBJS): pcfc11.h
codegen.o: codegen_win64.inc
ir.o irbuild.o irconst.o irflow.o copyflow.o irnumber.o valueflow.o irbits.o irbitcfg.o bitflow.o: ir.h

test/%.exe: pcfc11 test/%.c test/test.h $(wildcard include/*.h)
	./pcfc11 $(PCFCFLAGS) -Iinclude -Itest -c -o test/$*.o test/$*.c
	$(CC) -pthread -o $@ test/$*.o -xc test/common

test: $(TESTS)
	for i in $^; do echo $$i; ./$$i || exit 1; echo; done
	bash test/driver.sh ./pcfc11

test-all: test test-stage2

# Stage 2

stage2/pcfc11: $(OBJS:%=stage2/%)
	$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
	cp -R include stage2/

stage2/%.o: pcfc11 %.c
	mkdir -p stage2/test
	./pcfc11 $(BOOTSTRAPFLAGS) -c -o $(@D)/$*.o $*.c

stage2/ir.o stage2/irbuild.o stage2/irconst.o stage2/irflow.o stage2/copyflow.o stage2/irnumber.o stage2/valueflow.o stage2/irbits.o stage2/irbitcfg.o stage2/bitflow.o: ir.h

stage2/test/%.exe: stage2/pcfc11 test/%.c test/test.h $(wildcard include/*.h)
	mkdir -p stage2/test
	./stage2/pcfc11 $(PCFCFLAGS) -Iinclude -Itest -c -o stage2/test/$*.o test/$*.c
	$(CC) -pthread -o $@ stage2/test/$*.o -xc test/common

test-stage2: $(TESTS:test/%=stage2/test/%)
	for i in $^; do echo $$i; ./$$i || exit 1; echo; done
	bash test/driver.sh ./stage2/pcfc11

# Misc.

clean:
	rm -rf pcfc11 tmp* $(TESTS) test/*.s test/*.exe stage2
	find * -type f '(' -name '*~' -o -name '*.o' ')' -exec rm {} ';'

.PHONY: test clean test-stage2

check: pcfc11
	python3 tools/check.py --compiler ./pcfc11

.PHONY: check

check-constraints: pcfc11
	python3 tools/check_constraints.py --compiler ./pcfc11

check-abi: pcfc11
	python3 tools/check_sysv_abi.py --compiler ./pcfc11

check-robustness: pcfc11
	python3 tools/check_robustness.py --compiler ./pcfc11

.PHONY: check-constraints check-abi check-robustness

check-optimization: pcfc11
	python3 tools/check_optimization.py --compiler ./pcfc11

check-division: pcfc11
	python3 tools/check_division.py --compiler ./pcfc11

check-helpers: pcfc11
	python3 tools/check_helpers.py --compiler ./pcfc11

check-headers: pcfc11
	python3 tools/check_headers.py --compiler ./pcfc11

check-preprocessor: pcfc11
	python3 tools/check_preprocessor.py --compiler ./pcfc11

check-pycforge: pcfc11
	python3 tools/check_pycforge.py --compiler ./pcfc11

benchmark: pcfc11
	python3 tools/benchmark.py --compiler ./pcfc11

.PHONY: check-optimization check-division check-helpers check-headers check-preprocessor check-pycforge benchmark

check-initializers: pcfc11
	python3 tools/check_initializers.py --compiler ./pcfc11

.PHONY: check-initializers

check-bitfields: pcfc11
	python3 tools/check_bitfields.py --compiler ./pcfc11

.PHONY: check-bitfields

check-liveness: pcfc11
	python3 tools/check_liveness.py --compiler ./pcfc11

.PHONY: check-liveness

check-registers: pcfc11
	python3 tools/check_registers.py --compiler ./pcfc11

.PHONY: check-registers

check-expressions: pcfc11
	python3 tools/check_expressions.py --compiler ./pcfc11

.PHONY: check-expressions

check-diagnostics: pcfc11
	python3 tools/check_diagnostics.py --compiler ./pcfc11

.PHONY: check-diagnostics

check-numerics: pcfc11
	python3 tools/check_numerics.py --compiler ./pcfc11

.PHONY: check-numerics

check-copyflow: pcfc11
	python3 tools/check_copyflow.py --compiler ./pcfc11

.PHONY: check-copyflow

check-constcfg: pcfc11
	python3 tools/check_constcfg.py --compiler ./pcfc11

.PHONY: check-constcfg

check-csmith: pcfc11
	python3 tools/check_csmith.py --compiler ./pcfc11

check-upstream: pcfc11
	python3 tools/check_upstream.py --compiler ./pcfc11

.PHONY: check-csmith check-upstream

check-integer-codegen: pcfc11
	python3 tools/check_integer_codegen.py --compiler ./pcfc11

.PHONY: check-integer-codegen

check-valuenumber: pcfc11
	python3 tools/check_valuenumber.py --compiler ./pcfc11

.PHONY: check-valuenumber

check-knownbits: pcfc11
	python3 tools/check_knownbits.py --compiler ./pcfc11

.PHONY: check-knownbits

check-bitcfg: pcfc11
	python3 tools/check_bitcfg.py --compiler ./pcfc11

.PHONY: check-bitcfg

check-bitarith: pcfc11
	python3 tools/check_bitarith.py --compiler ./pcfc11

.PHONY: check-bitarith

# Remove discarded ordinary integer calculations only after valid liveness.
check-unused: pcfc11
	python3 tools/check_unused.py --compiler ./pcfc11

.PHONY: check-unused
