.PHONY: .FORCE

ARCH_DIR		:= compel/arch/$(ARCH)/plugins

#
# CFLAGS, ASFLAGS, LDFLAGS

# General compel includes
ccflags-y		+= -iquote $(SRC_DIR)/compel/include

# General compel/plugins includes
ccflags-y		+= -iquote $(obj)/include
ccflags-y		+= -iquote $(obj)/include/uapi
asflags-y		+= -iquote $(obj)/include
asflags-y		+= -iquote $(obj)/include/uapi

# Arch compel/plugins includes
ccflags-y		+= -iquote $(SRC_DIR)/$(ARCH_DIR)/include
asflags-y		+= -iquote $(SRC_DIR)/$(ARCH_DIR)/include
asflags-y		+= -iquote $(SRC_DIR)/$(ARCH_DIR)

# General flags for assembly
asflags-y		+= -Wstrict-prototypes -Wa,--noexecstack
asflags-y		+= -D__ASSEMBLY__ -nostdlib -fomit-frame-pointer

#
# Fds plugin
target			+= fds
fds-obj-y		+= fds/fds.o

#
# Shmem plugin
target			+= shmem
shmem-obj-y		+= shmem/shmem.o

#
# STD plugin
target			+= std
std-obj-y		+= std/std.o
std-obj-y		+= std/string.o
std-obj-y		+= ./$(ARCH_DIR)/std/syscalls-64.o
std-obj-y		+= ./$(ARCH_DIR)/std/call32.o
std-obj-y		+= ./$(ARCH_DIR)/std/prologue.o

sys-proto-generic	:= $(obj)/include/uapi/std/syscall.h
sys-codes-generic	:= $(obj)/include/uapi/std/syscall-codes.h
sys-codes		 = $(obj)/include/uapi/std/syscall-codes-$(1).h
sys-proto		 = $(obj)/include/uapi/std/syscall-$(1).h
sys-def			 = $(ARCH_DIR)/std/syscalls/syscall_$(1).tbl
sys-asm			 = $(ARCH_DIR)/std/syscalls-$(1).S
sys-asm-common-name	 = std/syscalls/syscall-common-x86-$(1).S
sys-asm-common		 = $(ARCH_DIR)/$(sys-asm-common-name)

sys-bits		:= 64

AV			:= $$$$

define gen-rule-sys-codes
$(sys-codes): $(sys-def)
	$(call msg-gen, $$@)
	$(Q) echo "/* Autogenerated, don't edit */"					>  $$@
	$(Q) echo "#ifndef ASM_SYSCALL_CODES_H_$(1)__"					>> $$@
	$(Q) echo "#define ASM_SYSCALL_CODES_H_$(1)__"					>> $$@
	$(Q) cat $$< | awk '/^__NR/{SYSN=$(AV)1;					\
		sub("^__NR", "SYS", SYSN);						\
		print "\n#ifndef ", $(AV)1;						\
		print "#define", $(AV)1, $(AV)2;					\
		print "#endif";								\
		print "\n#ifndef ", SYSN;						\
		print "#define ", SYSN, $(AV)1;						\
		print "#endif";}'							>> $$@
	$(Q) echo "#endif /* ASM_SYSCALL_CODES_H_$(1)__ */"				>> $$@
endef

define gen-rule-sys-proto
$(sys-proto): $(sys-def)
	$(call msg-gen, $$@)
	$(Q) echo "/* Autogenerated, don't edit */"					>  $$@
	$(Q) echo "#ifndef ASM_SYSCALL_PROTO_H_$(1)__"					>> $$@
	$(Q) echo "#define ASM_SYSCALL_PROTO_H_$(1)__"					>> $$@
	$(Q) echo '#include "std/syscall-codes-$(1).h"'					>> $$@
	$(Q) echo '#include "syscall-types.h"'						>> $$@
ifeq ($(1),32)
	$(Q) echo '#include "asm/syscall32.h"'						>> $$@
endif
	$(Q) cat $$< | awk '/^__NR/{print "extern long", $(AV)3,			\
			substr($(AV)0, index($(AV)0,$(AV)4)), ";"}'			>> $$@
	$(Q) echo "#endif /* ASM_SYSCALL_PROTO_H_$(1)__ */"				>> $$@
endef

define gen-rule-sys-asm
$(sys-asm): $(sys-def) $(sys-asm-common) $(sys-codes) $(sys-proto)
	$(call msg-gen, $$@)
	$(Q) echo "/* Autogenerated, don't edit */"					>  $$@
	$(Q) echo '#include "std/syscall-codes-$(1).h"'					>> $$@
	$(Q) echo '#include "$(sys-asm-common-name)"'					>> $$@
	$(Q) cat $$< | awk '/^__NR/{print "SYSCALL(", $(AV)3, ",", $(AV)2, ")"}'	>> $$@
endef

define gen-rule-sys-exec-tbl
$(sys-exec-tbl): $(sys-def) $(sys-codes) $(sys-proto) $(sys-proto-generic)
	$(call msg-gen, $$@)
	$(Q) echo "/* Autogenerated, don't edit */"					>  $$@
	$(Q) cat $$< | awk '/^__NR/{print						\
		"SYSCALL(", substr($(AV)3, 5), ",", $(AV)2, ")"}'			>> $$@
endef

$(sys-codes-generic): $(ARCH_DIR)/std/syscalls/syscall_32.tbl
	$(call msg-gen, $@)
	$(Q) echo "/* Autogenerated, don't edit */"			>  $@
	$(Q) echo "#ifndef __ASM_CR_SYSCALL_CODES_H__"			>> $@
	$(Q) echo "#define __ASM_CR_SYSCALL_CODES_H__"			>> $@
	$(Q) echo '#include "std/syscall-codes-64.h"'			>> $@
	$(Q) cat $< | awk '/^__NR/{NR32=$$1;				\
		sub("^__NR", "__NR32", NR32);				\
		print "\n#ifndef ", NR32;				\
		print "#define ", NR32, $$2;				\
		print "#endif";}'					>> $@
	$(Q) echo "#endif /* __ASM_CR_SYSCALL_CODES_H__ */"		>> $@

$(sys-proto-generic): $(strip $(call map,sys-proto,$(sys-bits)))
	$(call msg-gen, $@)
	$(Q) echo "/* Autogenerated, don't edit */"			>  $@
	$(Q) echo "#ifndef __ASM_CR_SYSCALL_PROTO_H__"			>> $@
	$(Q) echo "#define __ASM_CR_SYSCALL_PROTO_H__"			>> $@
	$(Q) echo ""							>> $@
	$(Q) echo "#ifdef CONFIG_X86_32"				>> $@
	$(Q) echo '#include "std/syscall-32.h"'				>> $@
	$(Q) echo "#else"						>> $@
	$(Q) echo '#include "std/syscall-64.h"'				>> $@
	$(Q) echo "#endif /* CONFIG_X86_32 */"				>> $@
	$(Q) echo ""							>> $@
	$(Q) echo "#endif /* __ASM_CR_SYSCALL_PROTO_H__ */"		>> $@

$(eval $(call map,gen-rule-sys-codes,$(sys-bits)))
$(eval $(call map,gen-rule-sys-proto,$(sys-bits)))
$(eval $(call map,gen-rule-sys-asm,$(sys-bits)))

std-headers-deps	+= $(call sys-codes,$(sys-bits))
std-headers-deps	+= $(call sys-proto,$(sys-bits))
std-headers-deps	+= $(call sys-asm,$(sys-bits))
std-headers-deps	+= $(sys-codes-generic)
std-headers-deps	+= $(sys-proto-generic)

$(addprefix $(obj)/,$(std-obj-y:%.o=%.d)): | $(std-headers-deps)
$(addprefix $(obj)/,$(std-obj-y:%.o=%.i)): | $(std-headers-deps)
$(addprefix $(obj)/,$(std-obj-y:%.o=%.s)): | $(std-headers-deps)
$(addprefix $(obj)/,$(std-obj-y)): | $(std-headers-deps)
