INC_PATH = inc
SRC_PATH = src
OBJ_PATH = obj
BIN_PATH = bin

CPP = g++
CPPFLAGS = -g -Wall -DCHECK -I$(INC_PATH)

CC = gcc
CFLAGS = -std=c99 -O3 -fomit-frame-pointer -I$(INC_PATH)
LDFLAGS = -lm

all: $(BIN_PATH) $(OBJ_PATH) as check c

$(BIN_PATH):
	mkdir -p $@

$(OBJ_PATH):
	mkdir -p $@

C_BIN += $(BIN_PATH)/bilintest-c
C_BIN += $(BIN_PATH)/speedtest-c

c: $(C_BIN)

AS_BIN += $(BIN_PATH)/bilintest-as
AS_BIN += $(BIN_PATH)/speedtest-as
AS_BIN += $(BIN_PATH)/test_curvepoint_multiscalar-as
AS_BIN += $(BIN_PATH)/test_twistpoint_multiscalar-as

as: $(AS_BIN)

CHECK_BIN += $(BIN_PATH)/bilintest-check
CHECK_BIN += $(BIN_PATH)/speedtest-check
CHECK_BIN += $(BIN_PATH)/test_curvepoint_multiscalar-check
CHECK_BIN += $(BIN_PATH)/test_twistpoint_multiscalar-check

check: $(CHECK_BIN)

COMMON_OBJ += $(OBJ_PATH)/linefunction_c.o
COMMON_OBJ += $(OBJ_PATH)/optate_c.o
COMMON_OBJ += $(OBJ_PATH)/fpe_c.o
COMMON_OBJ += $(OBJ_PATH)/fp2e_c.o
COMMON_OBJ += $(OBJ_PATH)/fp6e_c.o
COMMON_OBJ += $(OBJ_PATH)/fp12e_c.o
COMMON_OBJ += $(OBJ_PATH)/curvepoint_fp_c.o
COMMON_OBJ += $(OBJ_PATH)/twistpoint_fp2_c.o
COMMON_OBJ += $(OBJ_PATH)/final_expo_c.o
COMMON_OBJ += $(OBJ_PATH)/scalar_c.o
COMMON_OBJ += $(OBJ_PATH)/parameters_c.o
COMMON_OBJ += $(OBJ_PATH)/mul_c.o
COMMON_OBJ += $(OBJ_PATH)/mydouble_c.o

COMMON_AS_OBJ += $(patsubst %_c.o, %_c_with_as.o, $(COMMON_OBJ))

CHECK_SRC += $(patsubst $(OBJ_PATH)/%_c.o, $(SRC_PATH)/%.c, $(COMMON_OBJ))

$(BIN_PATH)/bilintest-check: $(SRC_PATH)/bilintest.c $(CHECK_SRC)
	$(CPP) $(CPPFLAGS) -DNTESTS=20 -o $@ $^

$(BIN_PATH)/bilintest-c: $(SRC_PATH)/bilintest.c $(COMMON_OBJ)
	$(CC) $(CFLAGS) -DNTESTS=1000 -o $@ $^ $(LDFLAGS)

$(BIN_PATH)/bilintest-as: $(SRC_PATH)/bilintest.c $(COMMON_AS_OBJ) $(OBJ_PATH)/asfunctions.a
	$(CC) $(CFLAGS) -no-pie -DQHASM -DNTESTS=1000000 -o $@ $^ $(LDFLAGS)

$(BIN_PATH)/speedtest-check: $(SRC_PATH)/speedtest.c $(CHECK_SRC)
	$(CPP) $(CPPFLAGS) -o $@ $^

$(BIN_PATH)/speedtest-c: $(SRC_PATH)/speedtest.c $(COMMON_OBJ)
	$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)

$(BIN_PATH)/speedtest-as: $(SRC_PATH)/speedtest.c $(COMMON_AS_OBJ) $(OBJ_PATH)/asfunctions.a
	$(CC) $(CFLAGS) -no-pie -DQHASM -o $@ $^ $(LDFLAGS)

TEST_SRC += $(SRC_PATH)/fpe.c
TEST_SRC += $(SRC_PATH)/scalar.c
TEST_SRC += $(SRC_PATH)/parameters.c
TEST_SRC += $(SRC_PATH)/mul.c
TEST_SRC += $(SRC_PATH)/mydouble.c
TEST_SRC += $(SRC_PATH)/heap_rootreplaced.s
TEST_SRC += $(SRC_PATH)/index_heap.c
TEST_SRC += $(SRC_PATH)/scalar_sub_nored.s

CURVE_TEST_SRC += $(TEST_SRC)
CURVE_TEST_SRC += $(SRC_PATH)/curvepoint_fp.c
CURVE_TEST_SRC += $(SRC_PATH)/curvepoint_fp_multiscalar.c

CURVE_TEST_AS_OBJ += $(patsubst $(SRC_PATH)/%.s, $(OBJ_PATH)/%_as.o, $(patsubst $(SRC_PATH)/%.c, $(OBJ_PATH)/%_c_with_as.o, $(CURVE_TEST_SRC)))

TWIST_TEST_SRC += $(TEST_SRC)
TWIST_TEST_SRC += $(SRC_PATH)/fp2e.c
TWIST_TEST_SRC += $(SRC_PATH)/twistpoint_fp2.c
TWIST_TEST_SRC += $(SRC_PATH)/twistpoint_fp2_multiscalar.c

TWIST_TEST_AS_OBJ += $(patsubst $(SRC_PATH)/%.s, $(OBJ_PATH)/%_as.o, $(patsubst $(SRC_PATH)/%.c, $(OBJ_PATH)/%_c_with_as.o, $(TWIST_TEST_SRC)))

$(BIN_PATH)/test_curvepoint_multiscalar-check: $(SRC_PATH)/test_curvepoint_multiscalar.c $(CURVE_TEST_SRC) $(OBJ_PATH)/asfunctions.a
	$(CPP) $(CPPFLAGS) -o $@ $^

$(BIN_PATH)/test_curvepoint_multiscalar-as: $(SRC_PATH)/test_curvepoint_multiscalar.c $(CURVE_TEST_AS_OBJ) $(OBJ_PATH)/asfunctions.a
	$(CC) $(CFLAGS) -no-pie -DQHASM -o $@ $^ $(LDFLAGS)

$(BIN_PATH)/test_twistpoint_multiscalar-check: $(SRC_PATH)/test_twistpoint_multiscalar.c $(TWIST_TEST_SRC) $(OBJ_PATH)/asfunctions.a
	$(CPP) $(CPPFLAGS) -o $@ $^

$(BIN_PATH)/test_twistpoint_multiscalar-as: $(SRC_PATH)/test_twistpoint_multiscalar.c $(TWIST_TEST_AS_OBJ) $(OBJ_PATH)/asfunctions.a
	$(CC) $(CFLAGS) -no-pie -DQHASM -o $@ $^ $(LDFLAGS)

AS_OBJ += $(OBJ_PATH)/fp2e_add2_as.o
AS_OBJ += $(OBJ_PATH)/fp2e_sub2_as.o
AS_OBJ += $(OBJ_PATH)/fp2e_double2_as.o
AS_OBJ += $(OBJ_PATH)/fp2e_triple2_as.o
AS_OBJ += $(OBJ_PATH)/fp2e_neg2_as.o
AS_OBJ += $(OBJ_PATH)/fp2e_mul_as.o
AS_OBJ += $(OBJ_PATH)/fp2e_mul_fpe_as.o
AS_OBJ += $(OBJ_PATH)/fp2e_short_coeffred_as.o
AS_OBJ += $(OBJ_PATH)/fp2e_add_as.o
AS_OBJ += $(OBJ_PATH)/fp2e_sub_as.o
AS_OBJ += $(OBJ_PATH)/fp2e_parallel_coeffmul_as.o
AS_OBJ += $(OBJ_PATH)/fp2e_mulxi_as.o
AS_OBJ += $(OBJ_PATH)/fp2e_double_as.o
AS_OBJ += $(OBJ_PATH)/fp2e_triple_as.o
AS_OBJ += $(OBJ_PATH)/fp2e_neg_as.o
AS_OBJ += $(OBJ_PATH)/fp2e_conjugate_as.o
AS_OBJ += $(OBJ_PATH)/fpe_mul_as.o
AS_OBJ += $(OBJ_PATH)/fp2e_square_as.o
AS_OBJ += $(OBJ_PATH)/consts_as.o

$(OBJ_PATH)/asfunctions.a: $(AS_OBJ)
	rm -f $@
	ar cr $@ $^

$(OBJ_PATH)/%_c.o: $(SRC_PATH)/%.c
	$(CC) $(CFLAGS) -c -o $@ $^

$(OBJ_PATH)/%_c_with_as.o: $(SRC_PATH)/%.c
	$(CC) $(CFLAGS) -DQHASM -c -o $@ $^

$(OBJ_PATH)/%_as.o: $(SRC_PATH)/%.s
	$(CC) $(CFLAGS) -fPIC -c -o $@ $^

.PHONY: clean

clean:
	-rm $(BIN_PATH)/*
	-rm $(OBJ_PATH)/*