From 5d1378349e1eb2364a21c3422602095ee83880b5 Mon Sep 17 00:00:00 2001 From: tyfkda Date: Sun, 17 Dec 2023 11:12:40 +0900 Subject: [PATCH] Enable specifying target architecture and platform on Makefile --- Makefile | 7 ++-- include/elf.h | 1 + src/cc/arch/aarch64/aarch64.h | 2 +- src/cc/arch/aarch64/emit_code.c | 4 +-- src/cc/arch/aarch64/ir_aarch64.c | 2 +- src/cc/arch/x64/ir_x64.c | 2 +- src/cc/arch/x64/x64.h | 2 +- src/cc/backend/codegen_expr.c | 4 +-- src/cc/backend/emit_util.c | 6 +--- src/cc/builtin.c | 4 +-- src/cc/frontend/fe_misc.c | 2 +- src/config.h | 57 ++++++++++++++++++++++++++++---- src/cpp/cpp.c | 5 --- src/xcc/main.c | 12 ++++--- 14 files changed, 75 insertions(+), 35 deletions(-) diff --git a/Makefile b/Makefile index 52c2d626c..5ad4de27c 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,7 @@ ifeq ("$(ARCHTYPE)", "") ARCHTYPE:=aarch64 endif endif +ARCHTYPE_UPPER:=$(shell echo "$(ARCHTYPE)" | tr \'[a-z]\' \'[A-Z]\') CC1_ARCH_DIR:=$(CC1_DIR)/arch/$(ARCHTYPE) CC1_FE_DIR:=$(CC1_DIR)/frontend @@ -104,7 +105,7 @@ $(foreach D, $(EXES), $(eval $(call DEFINE_EXE_TARGET,$(D)))) define DEFINE_OBJ_TARGET $(OBJ_DIR)/%.o: $(1)/%.c $(PARENT_DEPS) @mkdir -p $(OBJ_DIR) - $(CC) $(CFLAGS) -c -o $$@ $$< + $(CC) $(CFLAGS) -DXCC_TARGET_ARCH=XCC_ARCH_$(ARCHTYPE_UPPER) -c -o $$@ $$< endef XCC_SRC_DIRS:=$(XCC_DIR) $(CC1_FE_DIR) $(CC1_BE_DIR) $(CC1_DIR) $(CC1_ARCH_DIR) $(CPP_DIR) \ $(AS_DIR) $(LD_DIR) $(UTIL_DIR) $(DEBUG_DIR) @@ -171,7 +172,7 @@ test-self-hosting: self-hosting WCC_OBJ_DIR:=obj/wcc WCC_DIR:=src/wcc -WCC_CFLAGS:=$(CFLAGS) -I$(CPP_DIR) -DTARGET_WASM +WCC_CFLAGS:=$(CFLAGS) -I$(CPP_DIR) WCC_SRCS:=$(wildcard $(WCC_DIR)/*.c) \ $(wildcard $(CC1_FE_DIR)/*.c) \ @@ -186,7 +187,7 @@ wcc: $(PARENT_DEPS) $(WCC_OBJS) $(WCC_LIBS) define DEFINE_WCCOBJ_TARGET $(WCC_OBJ_DIR)/%.o: $(1)/%.c $(PARENT_DEPS) @mkdir -p $(WCC_OBJ_DIR) - $(CC) $(WCC_CFLAGS) -c -o $$@ $$< + $(CC) $(WCC_CFLAGS) -DXCC_TARGET_ARCH=XCC_ARCH_WASM -c -o $$@ $$< endef WCC_SRC_DIRS:=$(WCC_DIR) $(CC1_FE_DIR) $(CC1_BE_DIR) $(CC1_DIR) $(CPP_DIR) $(UTIL_DIR) $(foreach D, $(WCC_SRC_DIRS), $(eval $(call DEFINE_WCCOBJ_TARGET,$(D)))) diff --git a/include/elf.h b/include/elf.h index 8631573e2..9403d213e 100644 --- a/include/elf.h +++ b/include/elf.h @@ -60,6 +60,7 @@ struct proghdr { #define EM_386 (3) // Intel 80386 #define EM_X86_64 (62) // AMD x86-64 architecture #define EM_AARCH64 (183) // ARM AARCH64 +#define EM_RISCV (243) // RISC-V #define ET_REL (1) // Relocatable file #define ET_EXEC (2) // Executable file diff --git a/src/cc/arch/aarch64/aarch64.h b/src/cc/arch/aarch64/aarch64.h index 7b942bb66..011fe60ad 100644 --- a/src/cc/arch/aarch64/aarch64.h +++ b/src/cc/arch/aarch64/aarch64.h @@ -258,7 +258,7 @@ #define EMIT_ALIGN(x) emit_align_p2(x) -#ifdef __APPLE__ +#if XCC_TARGET_PLATFORM == XCC_PLATFORM_APPLE #define _RODATA() _SECTION("__DATA,__const") #define _LOCAL(x) ((void)0) #else diff --git a/src/cc/arch/aarch64/emit_code.c b/src/cc/arch/aarch64/emit_code.c index 0b24b68d9..4912a76d7 100644 --- a/src/cc/arch/aarch64/emit_code.c +++ b/src/cc/arch/aarch64/emit_code.c @@ -42,7 +42,7 @@ char *reg_offset(const char *base, const char *reg, const char *shift) { } char *label_at_page(char *label, int flag) { -#ifdef __APPLE__ +#if XCC_TARGET_PLATFORM == XCC_PLATFORM_APPLE static const char *s[] = { "%s@PAGE", "%s@PAGEOFF", "%s@GOTPAGE", "%s@GOTPAGEOFF", @@ -446,7 +446,7 @@ static void move_params_to_assigned(Function *func) { } } -#ifdef VAARG_ON_STACK +#if VAARG_ON_STACK bool vaargs = false; #else bool vaargs = func->type->func.vaargs; diff --git a/src/cc/arch/aarch64/ir_aarch64.c b/src/cc/arch/aarch64/ir_aarch64.c index 8b8e39427..3d2846e04 100644 --- a/src/cc/arch/aarch64/ir_aarch64.c +++ b/src/cc/arch/aarch64/ir_aarch64.c @@ -130,7 +130,7 @@ void mov_immediate(const char *dst, int64_t value, bool b64, bool is_unsigned) { } static bool is_got(const Name *name) { -#ifdef __APPLE__ +#if XCC_TARGET_PLATFORM == XCC_PLATFORM_APPLE // TODO: How to detect the label is GOT? return name->bytes >= 5 && strncmp(name->chars, "__std", 5) == 0; // __stdinp, etc. #else diff --git a/src/cc/arch/x64/ir_x64.c b/src/cc/arch/x64/ir_x64.c index 05b66b1a4..5105d519d 100644 --- a/src/cc/arch/x64/ir_x64.c +++ b/src/cc/arch/x64/ir_x64.c @@ -97,7 +97,7 @@ const RegAllocSettings kArchRegAllocSettings = { // static bool is_got(const Name *name) { -#ifdef __APPLE__ +#if XCC_TARGET_PLATFORM == XCC_PLATFORM_APPLE // TODO: How to detect the label is GOT? return name->bytes >= 5 && strncmp(name->chars, "__std", 5) == 0; // __stdinp, etc. #else diff --git a/src/cc/arch/x64/x64.h b/src/cc/arch/x64/x64.h index ea8a41c6c..91b15d0d9 100644 --- a/src/cc/arch/x64/x64.h +++ b/src/cc/arch/x64/x64.h @@ -201,7 +201,7 @@ #define EMIT_ALIGN(x) emit_align_p2(x) -#ifdef __APPLE__ +#if XCC_TARGET_PLATFORM == XCC_PLATFORM_APPLE #define _RODATA() _SECTION("__DATA,__const") #define _LOCAL(x) ((void)0) #else diff --git a/src/cc/backend/codegen_expr.c b/src/cc/backend/codegen_expr.c index eb66c2e8b..866d7fb8b 100644 --- a/src/cc/backend/codegen_expr.c +++ b/src/cc/backend/codegen_expr.c @@ -367,7 +367,7 @@ static Expr *simplify_funarg(Expr *arg) { case EX_MOD: case EX_LSHIFT: case EX_RSHIFT: -#if defined(__x86_64__) +#if XCC_TARGET_ARCH == XCC_ARCH_X64 // On x64, MUL, DIV and MOD instruction implicitly uses (breaks) %rdx // and %rdx is used as 3rd argument. // Similary, Shift instructions (SHL, SHR) uses %cl which is 4th argument. @@ -476,7 +476,7 @@ static VReg *gen_funcall(Expr *expr) { p->size = type_size(arg->type); p->is_flo = is_flonum(arg->type); p->stack_arg = is_stack_param(arg->type); -#if defined(VAARG_ON_STACK) +#if VAARG_ON_STACK if (functype->func.vaargs && functype->func.params != NULL && i >= functype->func.params->len) p->stack_arg = true; #endif diff --git a/src/cc/backend/emit_util.c b/src/cc/backend/emit_util.c index f742f9883..050afd1ec 100644 --- a/src/cc/backend/emit_util.c +++ b/src/cc/backend/emit_util.c @@ -11,10 +11,6 @@ #include "table.h" #include "util.h" -#ifdef __APPLE__ -#define MANGLE_PREFIX "_" -#endif - static FILE *emit_fp; char *fmt(const char *fm, ...) { @@ -134,7 +130,7 @@ void emit_align_p2(int align) { } void emit_bss(const char *label, size_t size, size_t align) { -#ifdef __APPLE__ +#if XCC_TARGET_PLATFORM == XCC_PLATFORM_APPLE fprintf(emit_fp, "\t.zerofill __DATA,__bss,%s,%zu,%d\n", label, size, most_significant_bit(align)); #else diff --git a/src/cc/builtin.c b/src/cc/builtin.c index b0590642e..811dc7f57 100644 --- a/src/cc/builtin.c +++ b/src/cc/builtin.c @@ -21,7 +21,7 @@ static Expr *proc_builtin_type_kind(const Token *ident) { return new_expr_fixlit(&tySize, ident, type->kind); } -#if defined(VAARG_ON_STACK) +#if VAARG_ON_STACK static VReg *gen_builtin_va_start(Expr *expr) { assert(expr->kind == EX_FUNCALL); Vector *args = expr->funcall.args; @@ -146,7 +146,7 @@ void install_builtins(void) { add_builtin_expr_ident("__builtin_type_kind", &p_reg_class); { -#if defined(VAARG_ON_STACK) +#if VAARG_ON_STACK Type *tyVaList = ptrof(&tyVoidPtr); #else Type *tyVaElem = create_struct_type(NULL, alloc_name("__va_elem", NULL, false), 0); diff --git a/src/cc/frontend/fe_misc.c b/src/cc/frontend/fe_misc.c index 64f89e545..786e1afec 100644 --- a/src/cc/frontend/fe_misc.c +++ b/src/cc/frontend/fe_misc.c @@ -699,7 +699,7 @@ Expr *extract_bitfield_value(Expr *src, const MemberInfo *minfo) { tmp = new_expr_bop(EX_BITAND, tmp->type, tmp->token, tmp, new_expr_fixlit(tmp->type, tmp->token, mask)); } else { -#if defined(__aarch64__) || defined(__WASM) || defined(TARGET_WASM) +#if XCC_TARGET_ARCH == XCC_ARCH_AARCH64 || XCC_TARGET_ARCH == XCC_ARCH_WASM const unsigned int MINREGSIZE = 4; int w = MAX(type_size(type), MINREGSIZE) * TARGET_CHAR_BIT; #else diff --git a/src/config.h b/src/config.h index b9a96ef18..9d16f321e 100644 --- a/src/config.h +++ b/src/config.h @@ -1,12 +1,49 @@ #pragma once -#if defined(__aarch64__) +// Architecture +#define XCC_ARCH_X64 1 +#define XCC_ARCH_AARCH64 2 +#define XCC_ARCH_RISCV64 3 +#define XCC_ARCH_WASM 4 + +#if !defined(XCC_TARGET_ARCH) +# if defined(__WASM) +# define XCC_TARGET_ARCH XCC_ARCH_WASM +# elif defined(__x86_64__) +# define XCC_TARGET_ARCH XCC_ARCH_X64 +# elif defined(__aarch64__) +# define XCC_TARGET_ARCH XCC_ARCH_AARCH64 +# elif defined(__riscv) && defined(__LP64__) +# define XCC_TARGET_ARCH XCC_ARCH_RISCV64 +# else +# error "Target architecture unspecified" +# endif +#endif + +// Apple, or not +#define XCC_PLATFORM_POSIX 1 +#define XCC_PLATFORM_APPLE 2 +#define XCC_PLATFORM_WASI 3 + +#if !XCC_TARGET_PLATFORM +# if defined(__WASM) || XCC_TARGET_ARCH == XCC_ARCH_WASM +# define XCC_TARGET_PLATFORM XCC_PLATFORM_WASI +# elif defined(__APPLE__) +# define XCC_TARGET_PLATFORM XCC_PLATFORM_APPLE +# else +# define XCC_TARGET_PLATFORM XCC_PLATFORM_POSIX +# endif +#endif + +// + +#if XCC_TARGET_ARCH == XCC_ARCH_AARCH64 # define AS_USE_CC -# if !defined(__APPLE__) +# if XCC_TARGET_PLATFORM != XCC_PLATFORM_APPLE # define NO_STD_LIB # endif -#elif !defined(__linux__) +#elif XCC_TARGET_ARCH != XCC_ARCH_X64 && XCC_TARGET_ARCH != XCC_ARCH_WASM # define AS_USE_CC #endif @@ -19,9 +56,13 @@ #define ALLOCA(size) malloc(size) #endif -#if defined(__APPLE__) && defined(__aarch64__) +#if !defined(VAARG_ON_STACK) && XCC_TARGET_PLATFORM == XCC_PLATFORM_APPLE && XCC_TARGET_ARCH == XCC_ARCH_AARCH64 // variadic arguments are passed through stack, not registers. -#define VAARG_ON_STACK +#define VAARG_ON_STACK 1 +#endif + +#if !defined(MANGLE_PREFIX) && XCC_TARGET_PLATFORM == XCC_PLATFORM_APPLE +#define MANGLE_PREFIX "_" #endif #define TARGET_CHAR_BIT 8 @@ -35,8 +76,10 @@ #endif // Elf -#if defined(__x86_64__) +#if XCC_TARGET_ARCH == XCC_ARCH_X64 #define MACHINE_TYPE EM_X86_64 -#elif defined(__aarch64__) +#elif XCC_TARGET_ARCH == XCC_ARCH_AARCH64 #define MACHINE_TYPE EM_AARCH64 +#elif XCC_TARGET_ARCH == XCC_ARCH_RISCV64 +#define MACHINE_TYPE EM_RISCV #endif diff --git a/src/cpp/cpp.c b/src/cpp/cpp.c index f22db5a46..8f2038bb9 100644 --- a/src/cpp/cpp.c +++ b/src/cpp/cpp.c @@ -11,11 +11,6 @@ int main(int argc, char *argv[]) { // Predefeined macros. define_macro("__XCC"); -#if defined(__linux__) - define_macro("__linux__"); -#elif defined(__APPLE__) - define_macro("__APPLE__"); -#endif #if defined(__NO_FLONUM) define_macro("__NO_FLONUM"); #endif diff --git a/src/xcc/main.c b/src/xcc/main.c index b0698d9ef..96b24d292 100644 --- a/src/xcc/main.c +++ b/src/xcc/main.c @@ -270,13 +270,17 @@ int main(int argc, char *argv[]) { Vector *cpp_cmd = new_vector(); vec_push(cpp_cmd, cpp_path); vec_push(cpp_cmd, "-D__LP64__"); // Memory model. -#if defined(__aarch64__) - vec_push(cpp_cmd, "-D__aarch64__"); -#elif defined(__x86_64__) +#if XCC_TARGET_ARCH == XCC_ARCH_X64 vec_push(cpp_cmd, "-D__x86_64__"); +#elif XCC_TARGET_ARCH == XCC_ARCH_AARCH64 + vec_push(cpp_cmd, "-D__aarch64__"); +#elif XCC_TARGET_ARCH == XCC_ARCH_RISCV64 + vec_push(cpp_cmd, "-D__riscv"); #endif -#if defined(__APPLE__) +#if XCC_TARGET_PLATFORM == XCC_PLATFORM_APPLE vec_push(cpp_cmd, "-D__APPLE__"); +#elif XCC_TARGET_PLATFORM == XCC_PLATFORM_POSIX + vec_push(cpp_cmd, "-D__linux__"); #endif Vector *cc1_cmd = new_vector();