diff --git a/src/build/build.h b/src/build/build.h index 90d336c09..223d297b4 100644 --- a/src/build/build.h +++ b/src/build/build.h @@ -6,10 +6,9 @@ #include "../version.h" #include "../utils/lib.h" -#define MAX_LIB_DIRS 1024 -#define MAX_FILES 2048 -#define MAX_ARGS 2048 -#define MAX_INCLUDES 2048 +#define MAX_BUILD_LIB_DIRS 1024 +#define MAX_COMMAND_LINE_FILES 2048 +#define MAX_COMMAND_LINE_RUN_ARGS 2048 #define MAX_THREADS 0xFFFF #define DEFAULT_SYMTAB_SIZE (256 * 1024) #define DEFAULT_SWITCHRANGE_MAX_SIZE (256) @@ -353,16 +352,16 @@ typedef enum typedef struct BuildOptions_ { - const char *lib_dir[MAX_LIB_DIRS]; - int lib_dir_count; - const char *libs[MAX_LIB_DIRS]; - int lib_count; - const char* linker_args[MAX_LIB_DIRS]; - int linker_arg_count; - const char* linker_lib_dir[MAX_LIB_DIRS]; - int linker_lib_dir_count; - const char* linker_libs[MAX_LIB_DIRS]; - int linker_lib_count; + const char *lib_dir[MAX_BUILD_LIB_DIRS]; + size_t lib_dir_count; + const char *libs[MAX_BUILD_LIB_DIRS]; + size_t lib_count; + const char* linker_args[MAX_BUILD_LIB_DIRS]; + size_t linker_arg_count; + const char* linker_lib_dir[MAX_BUILD_LIB_DIRS]; + size_t linker_lib_dir_count; + const char* linker_libs[MAX_BUILD_LIB_DIRS]; + size_t linker_lib_count; const char* std_lib_dir; VectorConv vector_conv; struct { @@ -510,6 +509,7 @@ typedef struct const char *version; const char *langrev; const char **source_dirs; + const char **test_source_dirs; const char **sources; const char **libdirs; const char **libs; @@ -666,6 +666,16 @@ static BuildTarget default_build_target = { .switchrange_max_size = DEFAULT_SWITCHRANGE_MAX_SIZE, }; +extern const char *project_default_keys[][2]; +extern const int project_default_keys_count; +extern const char *project_target_keys[][2]; +extern const int project_target_keys_count; +extern const char *manifest_default_keys[][2]; +extern const int manifest_default_keys_count; +extern const char *manifest_target_keys[][2]; +extern const int manifest_target_keys_count; +extern char *arch_os_target[ARCH_OS_TARGET_LAST + 1]; + BuildOptions parse_arguments(int argc, const char *argv[]); ArchOsTarget arch_os_target_from_string(const char *target); bool command_accepts_files(CompilerCommand command); diff --git a/src/build/build_internal.h b/src/build/build_internal.h index d4d9290e7..1c45f8c6a 100644 --- a/src/build/build_internal.h +++ b/src/build/build_internal.h @@ -12,6 +12,9 @@ typedef struct BuildTarget **targets; } Project; +#define COPY_IF_DEFAULT(target__, value__) \ + do { if ((int)target__ == -1) target__ = value__; } while(0) + extern bool silence_deprecation; extern const char *trust_level[3]; diff --git a/src/build/build_options.c b/src/build/build_options.c index a6a8481f2..669862404 100644 --- a/src/build/build_options.c +++ b/src/build/build_options.c @@ -10,10 +10,10 @@ bool silence_deprecation; static int arg_index; static int arg_count; -static const char** args; -static const char* current_arg; -extern const char* llvm_version; -extern const char* llvm_target; +static const char **args; +static const char *current_arg; +extern const char *llvm_version; +extern const char *llvm_target; char *arch_os_target[ARCH_OS_TARGET_LAST + 1] = { [ELF_AARCH64] = "elf-aarch64", @@ -192,8 +192,7 @@ static void usage(void) } - -static const char* check_dir(const char *path) +static const char *check_dir(const char *path) { static char *original_path = NULL; if (!original_path) @@ -210,7 +209,7 @@ static inline bool at_end() return arg_index == arg_count - 1; } -static inline const char* next_arg() +static inline const char *next_arg() { assert(!at_end()); current_arg = args[++arg_index]; @@ -223,12 +222,12 @@ static inline bool next_is_opt() return args[arg_index + 1][0] == '-'; } -INLINE bool match_longopt(const char* name) +INLINE bool match_longopt(const char *name) { return str_eq(¤t_arg[2], name); } -static inline const char *match_argopt(const char* name) +static inline const char *match_argopt(const char *name) { size_t len = strlen(name); if (memcmp(¤t_arg[2], name, len) != 0) return false; @@ -236,7 +235,7 @@ static inline const char *match_argopt(const char* name) return ¤t_arg[2 + len + 1]; } -static inline bool match_shortopt(const char* name) +static inline bool match_shortopt(const char *name) { return strcmp(¤t_arg[1], name) == 0; } @@ -244,9 +243,9 @@ static inline bool match_shortopt(const char* name) void append_file(BuildOptions *build_options) { - if (vec_size(build_options->files) == MAX_FILES) + if (vec_size(build_options->files) == MAX_COMMAND_LINE_FILES) { - EOUTPUT("Max %d files may be specified.", MAX_FILES); + EOUTPUT("Max %d files may be specified.", MAX_COMMAND_LINE_FILES); exit_compiler(EXIT_FAILURE); } vec_add(build_options->files, current_arg); @@ -254,9 +253,9 @@ void append_file(BuildOptions *build_options) void append_arg(BuildOptions *build_options) { - if (vec_size(build_options->args) == MAX_ARGS) + if (vec_size(build_options->args) == MAX_COMMAND_LINE_RUN_ARGS) { - EOUTPUT("Max %d args may be specified.", MAX_ARGS); + EOUTPUT("Max %d args may be specified.", MAX_COMMAND_LINE_RUN_ARGS); exit_compiler(EXIT_FAILURE); } vec_add(build_options->args, current_arg); @@ -279,7 +278,7 @@ static void parse_optional_target(BuildOptions *options) } } -static void project_usage() +static void project_usage() { PRINTF("Usage: %s [] project []", args[0]); PRINTF(""); @@ -287,9 +286,9 @@ static void project_usage() PRINTF(" view view the current projects structure"); } -static void parse_project_subcommand(BuildOptions *options) +static void parse_project_subcommand(BuildOptions *options) { - if (arg_match("view")) + if (arg_match("view")) { options->subcommand = SUBCOMMAND_VIEW; return; @@ -299,7 +298,7 @@ static void parse_project_subcommand(BuildOptions *options) static void parse_project_options(BuildOptions *options) { - if (at_end()) + if (at_end()) { project_usage(); return; @@ -444,6 +443,7 @@ static void parse_command(BuildOptions *options) } FAIL_WITH_ERR("Cannot process the unknown command \"%s\".", current_arg); } + static void print_all_targets(void) { PRINTF("Available targets:"); @@ -463,9 +463,9 @@ static void print_version(void) static void add_linker_arg(BuildOptions *options, const char *arg) { - if (options->linker_arg_count == MAX_LIB_DIRS) + if (options->linker_arg_count == MAX_BUILD_LIB_DIRS) { - error_exit("Too many linker arguments are given, more than %d\n", MAX_LIB_DIRS); + error_exit("Too many linker arguments are given, more than %d\n", MAX_BUILD_LIB_DIRS); } options->linker_args[options->linker_arg_count++] = arg; } @@ -506,7 +506,7 @@ void update_feature_flags(const char ***flags, const char ***removed_flags, cons vec_add(*to_add_to_ref, arg); } -static int parse_multi_option(const char *start, unsigned count, const char** elements) +static int parse_multi_option(const char *start, unsigned count, const char **elements) { const char *arg = current_arg; int select = str_findlist(start, count, elements); @@ -724,7 +724,8 @@ static void parse_option(BuildOptions *options) print_version(); exit_compiler(COMPILER_SUCCESS_EXIT); } - if (match_longopt("run-once")) { + if (match_longopt("run-once")) + { options->run_once = true; return; } @@ -1089,23 +1090,24 @@ static void parse_option(BuildOptions *options) if (str_has_suffix(name, ".c3l")) { error_exit("When specifying libraries, the .c3l suffix should" - " not be included, so rather than '--lib %s', try using '--lib %s' instead.", - name, str_remove_suffix(name, ".c3l")); + " not be included, so rather than '--lib %s', try using '--lib %s' instead.", + name, str_remove_suffix(name, ".c3l")); } if (str_has_suffix(name, ".lib") || str_has_suffix(name, ".a") - || str_has_suffix(name, ".dll") || str_has_suffix(name, ".so")) + || str_has_suffix(name, ".dll") || str_has_suffix(name, ".so")) { error_exit("You tried to add '%s' as a C3 library, but from the name it appears to be a" - " static/dynamic library. To link with such a library, use '-l ' instead.", - name); + " static/dynamic library. To link with such a library, use '-l ' instead.", + name); } char *name_copy = strdup(name); str_ellide_in_place(name_copy, 32); if (strchr(name, '/') != NULL || (PLATFORM_WINDOWS && strchr(name, '\\') != NULL)) { - error_exit("There is a problem including the library '%s': a library name should never contain the path. Use '--libdir' to add the " - "directory to the library search paths, then use the plain name for '--lib', " - "e.g '--libdir my_project/libs --lib some_lib'.", name_copy); + error_exit( + "There is a problem including the library '%s': a library name should never contain the path. Use '--libdir' to add the " + "directory to the library search paths, then use the plain name for '--lib', " + "e.g '--libdir my_project/libs --lib some_lib'.", name_copy); } error_exit("Invalid library name '%s', it should be something like 'foo_lib'.", name_copy); } @@ -1115,7 +1117,7 @@ static void parse_option(BuildOptions *options) if (match_longopt("libdir")) { if (at_end() || next_is_opt()) error_exit("error: --libdir needs a directory."); - if (options->lib_dir_count == MAX_LIB_DIRS) error_exit("Max %d library directories may be specified.", MAX_LIB_DIRS); + if (options->lib_dir_count == MAX_BUILD_LIB_DIRS) error_exit("Max %d library directories may be specified.", MAX_BUILD_LIB_DIRS); options->lib_dir[options->lib_dir_count++] = check_dir(next_arg()); return; } @@ -1242,7 +1244,8 @@ BuildOptions parse_arguments(int argc, const char *argv[]) for (arg_index = 1; arg_index < arg_count; arg_index++) { current_arg = args[arg_index]; - if (collecting_args) { + if (collecting_args) + { append_arg(&build_options); continue; } diff --git a/src/build/builder.c b/src/build/builder.c index b1fe7d235..a3e794132 100644 --- a/src/build/builder.c +++ b/src/build/builder.c @@ -139,7 +139,7 @@ void update_build_target_with_opt_level(BuildTarget *target, OptimizationSetting AutoVectorization slp_vectorization = VECTORIZATION_OFF; MergeFunctions merge_functions = MERGE_FUNCTIONS_OFF; ShowBacktrace show_backtrace = SHOW_BACKTRACE_ON; - bool single_module = false; + SingleModule single_module = SINGLE_MODULE_OFF; FpOpt fp_opt = FP_STRICT; switch (level) { @@ -163,7 +163,7 @@ void update_build_target_with_opt_level(BuildTarget *target, OptimizationSetting merge_functions = MERGE_FUNCTIONS_ON; optlevel = OPTIMIZATION_MORE; safety_level = SAFETY_OFF; - single_module = true; + single_module = SINGLE_MODULE_ON; slp_vectorization = VECTORIZATION_ON; unroll_loops = UNROLL_LOOPS_ON; vectorization = VECTORIZATION_ON; @@ -174,7 +174,7 @@ void update_build_target_with_opt_level(BuildTarget *target, OptimizationSetting optlevel = OPTIMIZATION_AGGRESSIVE; panic_level = PANIC_OFF; safety_level = SAFETY_OFF; - single_module = true; + single_module = SINGLE_MODULE_ON; slp_vectorization = VECTORIZATION_ON; unroll_loops = UNROLL_LOOPS_ON; vectorization = VECTORIZATION_ON; @@ -185,7 +185,7 @@ void update_build_target_with_opt_level(BuildTarget *target, OptimizationSetting optlevel = OPTIMIZATION_AGGRESSIVE; panic_level = PANIC_OFF; safety_level = SAFETY_OFF; - single_module = true; + single_module = SINGLE_MODULE_ON; slp_vectorization = VECTORIZATION_ON; unroll_loops = UNROLL_LOOPS_ON; vectorization = VECTORIZATION_ON; @@ -207,7 +207,7 @@ void update_build_target_with_opt_level(BuildTarget *target, OptimizationSetting panic_level = PANIC_OFF; safety_level = SAFETY_OFF; show_backtrace = SHOW_BACKTRACE_OFF; - single_module = true; + single_module = SINGLE_MODULE_ON; slp_vectorization = VECTORIZATION_ON; vectorization = VECTORIZATION_OFF; break; @@ -215,19 +215,21 @@ void update_build_target_with_opt_level(BuildTarget *target, OptimizationSetting default: UNREACHABLE } - if (target->optsize == SIZE_OPTIMIZATION_NOT_SET) target->optsize = optsize; - if (target->optlevel == OPTIMIZATION_NOT_SET) target->optlevel = optlevel; - if (target->show_backtrace == SHOW_BACKTRACE_NOT_SET) target->show_backtrace = show_backtrace; - if (target->feature.safe_mode == SAFETY_NOT_SET) target->feature.safe_mode = safety_level; - if (target->feature.panic_level == PANIC_NOT_SET) target->feature.panic_level = panic_level; - if (target->debug_info == DEBUG_INFO_NOT_SET) target->debug_info = debug; - if (target->feature.fp_math == FP_DEFAULT) target->feature.fp_math = fp_opt; - if (target->single_module == SINGLE_MODULE_NOT_SET && single_module) target->single_module = SINGLE_MODULE_ON; - if (target->unroll_loops == UNROLL_LOOPS_NOT_SET) target->unroll_loops = unroll_loops; - if (target->merge_functions == MERGE_FUNCTIONS_NOT_SET) target->merge_functions = merge_functions; - if (target->slp_vectorization == VECTORIZATION_NOT_SET) target->slp_vectorization = slp_vectorization; - if (target->loop_vectorization == VECTORIZATION_NOT_SET) target->loop_vectorization = vectorization; + COPY_IF_DEFAULT(target->optsize, optsize); + COPY_IF_DEFAULT(target->optlevel, optlevel); + COPY_IF_DEFAULT(target->show_backtrace, show_backtrace); + COPY_IF_DEFAULT(target->feature.safe_mode, safety_level); + COPY_IF_DEFAULT(target->feature.panic_level, panic_level); + COPY_IF_DEFAULT(target->debug_info, debug); + COPY_IF_DEFAULT(target->feature.fp_math, fp_opt); + COPY_IF_DEFAULT(target->unroll_loops, unroll_loops); + COPY_IF_DEFAULT(target->merge_functions, merge_functions); + COPY_IF_DEFAULT(target->slp_vectorization, slp_vectorization); + COPY_IF_DEFAULT(target->loop_vectorization, vectorization); + COPY_IF_DEFAULT(target->single_module, single_module); } + + static void update_build_target_from_options(BuildTarget *target, BuildOptions *options) { switch (options->command) @@ -327,15 +329,15 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions * if (options->silence_deprecation) target->silence_deprecation = options->silence_deprecation; target->print_linking = options->print_linking; - for (int i = 0; i < options->linker_arg_count; i++) + for (size_t i = 0; i < options->linker_arg_count; i++) { vec_add(target->link_args, options->linker_args[i]); } - for (int i = 0; i < options->linker_lib_dir_count; i++) + for (size_t i = 0; i < options->linker_lib_dir_count; i++) { vec_add(target->linker_libdirs, options->linker_lib_dir[i]); } - for (int i = 0; i < options->linker_lib_count; i++) + for (size_t i = 0; i < options->linker_lib_count; i++) { vec_add(target->linker_libs, options->linker_libs[i]); } @@ -369,10 +371,7 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions * if (options->win.crt_linking != WIN_CRT_DEFAULT) target->win.crt_linking = options->win.crt_linking; if (options->linuxpaths.crt) target->linuxpaths.crt = options->linuxpaths.crt; if (options->linuxpaths.crtbegin) target->linuxpaths.crtbegin = options->linuxpaths.crtbegin; - if (options->fp_math != FP_DEFAULT) - { - target->feature.fp_math = options->fp_math; - } + if (options->fp_math != FP_DEFAULT) target->feature.fp_math = options->fp_math; if (options->x86_vector_capability != X86VECTOR_DEFAULT) { target->feature.x86_vector_capability = options->x86_vector_capability; diff --git a/src/build/common_build.c b/src/build/common_build.c index 09ed433d9..8188fcdb8 100644 --- a/src/build/common_build.c +++ b/src/build/common_build.c @@ -2,6 +2,7 @@ #include "utils/common.h" #include + void check_json_keys(const char* valid_keys[][2], size_t key_count, const char* deprecated_keys[], size_t deprecated_key_count, JSONObject *json, const char *target_name, const char *option) { static bool failed_shown = false; diff --git a/src/build/libraries.c b/src/build/libraries.c index 820676342..fba7dc98d 100644 --- a/src/build/libraries.c +++ b/src/build/libraries.c @@ -71,15 +71,16 @@ static inline void parse_library_type(Library *library, LibraryTarget ***target_ static inline void parse_library_target(Library *library, LibraryTarget *target, const char *target_name, JSONObject *object) { - target->link_flags = get_string_array(library->dir, target_name, object, "linkflags", false); + target->link_flags = target->link_flags = get_string_array(library->dir, target_name, object, "link-args", false); + if (!target->link_flags) { - target->link_flags = get_string_array(library->dir, target_name, object, "link-args", false); + target->link_flags = get_string_array(library->dir, target_name, object, "linkflags", false); } - target->linked_libs = get_string_array(library->dir, target_name, object, "linked-libs", false); + target->linked_libs = get_string_array(library->dir, target_name, object, "linked-libraries", false); if (!target->linked_libs) { - target->linked_libs = get_string_array(library->dir, target_name, object, "linked-libraries", false); + target->linked_libs = get_string_array(library->dir, target_name, object, "linked-libs", false); } target->dependencies = get_string_array(library->dir, target_name, object, "dependencies", false); target->execs = get_string_array(library->dir, target_name, object, "exec", false); @@ -240,7 +241,7 @@ void resolve_libraries(BuildTarget *build_target) DEBUG_LOG("Search '.'"); file_add_wildcard_files(&c3_libs, ".", false, &c3lib_suffix, 1); } - Library *libraries[MAX_LIB_DIRS * 2]; + Library *libraries[MAX_BUILD_LIB_DIRS * 2]; size_t lib_count = 0; FOREACH(const char *, lib, c3_libs) { @@ -255,7 +256,7 @@ void resolve_libraries(BuildTarget *build_target) size_t size; json = read_manifest(lib, file_read_all(manifest_path, &size)); } - if (lib_count == MAX_LIB_DIRS * 2) error_exit("Too many libraries added, exceeded %d.", MAX_LIB_DIRS * 2); + if (lib_count == MAX_BUILD_LIB_DIRS * 2) error_exit("Too many libraries added, exceeded %d.", MAX_BUILD_LIB_DIRS * 2); libraries[lib_count++] = add_library(json, lib); } FOREACH(const char *, lib_name, build_target->libs) diff --git a/src/build/project.c b/src/build/project.c index 15c465505..5a063a86f 100644 --- a/src/build/project.c +++ b/src/build/project.c @@ -2,15 +2,9 @@ // Use of this source code is governed by a LGPLv3.0 // a copy of which can be found in the LICENSE file. -#include #include "build_internal.h" #include "utils/json.h" -#define MAX_SYMTAB_SIZE (1024 * 1024) - -#define GET_SETTING(type__, key__, strings__, comment__) \ - (type__)get_valid_string_setting(PROJECT_JSON, target_name, json, key__, strings__, 0, ELEMENTLEN(strings__), comment__) - const char *project_default_keys[][2] = { {"authors", "Authors, optionally with email."}, {"benchfn", "Override the benchmark function."}, @@ -133,10 +127,13 @@ const char* project_target_keys[][2] = { }; const int project_target_keys_count = ELEMENTLEN(project_target_keys); - const int project_deprecated_target_keys_count = ELEMENTLEN(project_deprecated_target_keys); +#define MAX_SYMTAB_SIZE (1024 * 1024) +#define GET_SETTING(type__, key__, strings__, comment__) \ + (type__)get_valid_string_setting(PROJECT_JSON, target_name, json, key__, strings__, 0, ELEMENTLEN(strings__), comment__) +// Json -> target / default target static void load_into_build_target(JSONObject *json, const char *target_name, BuildTarget *target) { if (target_name) @@ -147,15 +144,19 @@ static void load_into_build_target(JSONObject *json, const char *target_name, Bu { check_json_keys(project_default_keys, project_default_keys_count, NULL, 0, json, "default target", "--list-project-properties"); } + + // The default c compiler name target->cc = get_string(PROJECT_JSON, target_name, json, "cc", target->cc); + // Where to find and execute the scripts target->script_dir = get_string(PROJECT_JSON, target_name, json, "script-dir", target->script_dir); - // Exec - get_list_append_strings(PROJECT_JSON, target_name, json, &target->exec, "exec", "exec-override", "exec-add"); - + // The output directory target->output_dir = get_string(PROJECT_JSON, target_name, json,"output", target->output_dir); + // "Before compilation" execution + get_list_append_strings(PROJECT_JSON, target_name, json, &target->exec, "exec", "exec-override", "exec-add"); + // CFlags target->cflags = get_cflags(PROJECT_JSON, target_name, json, target->cflags); @@ -168,6 +169,9 @@ static void load_into_build_target(JSONObject *json, const char *target_name, Bu // Sources get_list_append_strings(PROJECT_JSON, target_name, json, &target->source_dirs, "sources", "sources-override", "sources-add"); + // Test sources + get_list_append_strings(PROJECT_JSON, target_name, json, &target->test_source_dirs, "test-sources", "test-sources-override", "test-sources-add"); + // Linked-libraries - libraries to add at link time get_list_append_strings(PROJECT_JSON, target_name, json, &target->linker_libs, "linked-libraries", "linked-libraries-override", "linked-libraries-add"); @@ -383,11 +387,15 @@ static void load_into_build_target(JSONObject *json, const char *target_name, Bu // Use the fact that they correspond to 0, 1, -1 target->feature.x86_struct_return = get_valid_bool(PROJECT_JSON, target_name, json, "x86-stack-struct-return", target->feature.x86_struct_return); + + // Soft float target->feature.soft_float = get_valid_bool(PROJECT_JSON, target_name, json, "soft-float", target->feature.soft_float); + + // Win64 simd feature switch target->feature.pass_win64_simd_as_arrays = get_valid_bool(PROJECT_JSON, target_name, json, "win64-simd-array", target->feature.pass_win64_simd_as_arrays); - } + static void project_add_target(Project *project, BuildTarget *default_target, JSONObject *json, const char *name, const char *type, TargetType target_type) { assert(json->type == J_OBJECT); diff --git a/src/compiler/abi/c_abi.c b/src/compiler/abi/c_abi.c index 44568ccab..ac9931d8e 100644 --- a/src/compiler/abi/c_abi.c +++ b/src/compiler/abi/c_abi.c @@ -193,7 +193,7 @@ void c_abi_func_create(FunctionPrototype *proto) { assert(!proto->is_resolved); proto->is_resolved = true; - switch (platform_target.abi) + switch (compiler.platform.abi) { case ABI_X64: c_abi_func_create_x64(proto); @@ -240,7 +240,7 @@ ABIArgInfo *c_abi_classify_argument_type_default(Type *type) // Struct-likes are returned by sret if (type_is_abi_aggregate(type)) return abi_arg_new_indirect_by_val(type); - if (type_is_int128(type) && !platform_target.int128) return abi_arg_new_indirect_by_val(type); + if (type_is_int128(type) && !compiler.platform.int128) return abi_arg_new_indirect_by_val(type); // Otherwise do we have a type that needs promotion? if (type_is_promotable_int_bool(type)) return abi_arg_new_direct_int_ext(type); diff --git a/src/compiler/abi/c_abi_aarch64.c b/src/compiler/abi/c_abi_aarch64.c index 4379ce543..6c9ca0153 100644 --- a/src/compiler/abi/c_abi_aarch64.c +++ b/src/compiler/abi/c_abi_aarch64.c @@ -61,7 +61,7 @@ ABIArgInfo *aarch64_coerce_illegal_vector(Type *type) TypeSize size = type_size(type); // CLANG: Android promotes char[<2>] to ushort, not uint - if (platform_target.environment_type == ENV_TYPE_ANDROID && size <= 2) + if (compiler.platform.environment_type == ENV_TYPE_ANDROID && size <= 2) { return abi_arg_new_direct_coerce_type(type_ushort); } @@ -92,7 +92,7 @@ ABIArgInfo *aarch64_classify_argument_type(Type *type) { // Over 128 bits should be indirect, but // we don't have that (yet?) - if (type_is_promotable_int_bool(type) && platform_target.aarch64.is_darwin_pcs) + if (type_is_promotable_int_bool(type) && compiler.platform.aarch64.is_darwin_pcs) { return abi_arg_new_direct_int_ext(type); } @@ -120,7 +120,7 @@ ABIArgInfo *aarch64_classify_argument_type(Type *type) { // For RenderScript <= 16 needs to be coerced. AlignSize alignment = type_abi_alignment(type); - if (platform_target.aarch64.is_aapcs) + if (compiler.platform.aarch64.is_aapcs) { alignment = alignment < 16 ? 8 : 16; } @@ -167,7 +167,7 @@ ABIArgInfo *aarch64_classify_return_type(Type *type, bool variadic) if (!type_is_abi_aggregate(type)) { - if (type_is_promotable_int_bool(type) && platform_target.aarch64.is_darwin_pcs) + if (type_is_promotable_int_bool(type) && compiler.platform.aarch64.is_darwin_pcs) { return abi_arg_new_direct_int_ext(type); } @@ -182,7 +182,7 @@ ABIArgInfo *aarch64_classify_return_type(Type *type, bool variadic) Type *base = NULL; unsigned members = 0; if (type_is_homogenous_aggregate(type, &base, &members) && - !(platform_target.arch == ARCH_TYPE_AARCH64_32 && variadic)) + !(compiler.platform.arch == ARCH_TYPE_AARCH64_32 && variadic)) { return abi_arg_new_direct(); } @@ -194,7 +194,7 @@ ABIArgInfo *aarch64_classify_return_type(Type *type, bool variadic) // this is case is ignored here but needs to be added // in case it is to be supported. - if (size <= 8 && !platform_target.big_endian) + if (size <= 8 && !compiler.platform.big_endian) { return abi_arg_new_direct_coerce_type(type_int_unsigned_by_bitsize(size * 8)); } diff --git a/src/compiler/abi/c_abi_riscv.c b/src/compiler/abi/c_abi_riscv.c index 9863592ab..8409f2086 100644 --- a/src/compiler/abi/c_abi_riscv.c +++ b/src/compiler/abi/c_abi_riscv.c @@ -28,11 +28,11 @@ static bool riscv_detect_fpcc_struct_internal(Type *type, unsigned current_offse { bool is_int = type_is_integer_or_bool_kind(type); bool is_float = type_is_float(type); - unsigned flen = platform_target.riscv.flen; + unsigned flen = compiler.platform.riscv.flen; ByteSize size = type_size(type); if (is_int || is_float) { - if (is_int && size > platform_target.riscv.xlen) return false; + if (is_int && size > compiler.platform.riscv.xlen) return false; // Can't be eligible if larger than the FP registers. Half precision isn't // currently supported on RISC-V and the ABI hasn't been confirmed, so // default to the integer ABI in that case. @@ -134,19 +134,19 @@ static ABIArgInfo *riscv_classify_argument_type(Type *type, bool is_fixed, unsig assert(type == type->canonical); - unsigned xlen = platform_target.riscv.xlen; + unsigned xlen = compiler.platform.riscv.xlen; assert(is_power_of_two(xlen)); ByteSize size = type_size(type); // Pass floating point values via FPRs if possible. - if (is_fixed && type_is_float(type) && platform_target.riscv.flen >= size && *fprs) + if (is_fixed && type_is_float(type) && compiler.platform.riscv.flen >= size && *fprs) { (*fprs)--; return abi_arg_new_direct(); } - if (is_fixed && platform_target.riscv.flen && type->type_kind == TYPE_STRUCT) + if (is_fixed && compiler.platform.riscv.flen && type->type_kind == TYPE_STRUCT) { AbiType field1, field2; unsigned offset1 = 0; @@ -216,7 +216,7 @@ static ABIArgInfo *riscv_classify_argument_type(Type *type, bool is_fixed, unsig { return abi_arg_new_direct_coerce_type(type_int_unsigned_by_bitsize(xlen * 8)); } - if (alignment == 2 * platform_target.riscv.xlen) + if (alignment == 2 * compiler.platform.riscv.xlen) { return abi_arg_new_direct_coerce_type(type_int_unsigned_by_bitsize(xlen * 16)); } @@ -231,7 +231,7 @@ static ABIArgInfo *riscv_classify_return(Type *return_type) if (type_is_void(return_type)) return abi_arg_ignore(); unsigned arg_gpr_left = 2; - unsigned arg_fpr_left = platform_target.riscv.flen ? 2 : 0; + unsigned arg_fpr_left = compiler.platform.riscv.flen ? 2 : 0; // The rules for return and argument types are the same, so defer to // classifyArgumentType. @@ -263,7 +263,7 @@ void c_abi_func_create_riscv(FunctionPrototype *prototype) // in LLVM IR, relying on the backend lowering code to rewrite the argument // list and pass indirectly on RV32. bool is_ret_indirect = abi_arg_is_indirect(ret_abi); - if (type_is_scalar(ret_type) && type_size(ret_type) > 2 * platform_target.riscv.xlen) + if (type_is_scalar(ret_type) && type_size(ret_type) > 2 * compiler.platform.riscv.xlen) { // Normal scalar > 2 * XLen, e.g. f128 on RV32 is_ret_indirect = true; @@ -274,7 +274,7 @@ void c_abi_func_create_riscv(FunctionPrototype *prototype) // different for variadic arguments, we must also track whether we are // examining a vararg or not. unsigned arg_gprs_left = is_ret_indirect ? gpr - 1 : gpr; - unsigned arg_fprs_left = platform_target.riscv.flen ? fpr : 0; + unsigned arg_fprs_left = compiler.platform.riscv.flen ? fpr : 0; // If we have an optional, then the return type is a parameter. if (prototype->ret_by_ref) diff --git a/src/compiler/abi/c_abi_win64.c b/src/compiler/abi/c_abi_win64.c index 6e9b45e64..b84d4fd85 100644 --- a/src/compiler/abi/c_abi_win64.c +++ b/src/compiler/abi/c_abi_win64.c @@ -36,7 +36,7 @@ ABIArgInfo *win64_classify(Regs *regs, Type *type, bool is_return, bool is_vecto // => to main handling. } ByteSize size = type_size(type); - bool type_is_vector_to_pass_as_array = active_target.feature.pass_win64_simd_as_arrays && type_flat_is_vector(type); + bool type_is_vector_to_pass_as_array = compiler.build.feature.pass_win64_simd_as_arrays && type_flat_is_vector(type); if (type_is_vector_to_pass_as_array || type_is_abi_aggregate(type)) { // Not 1, 2, 4, 8? Pass indirect. diff --git a/src/compiler/abi/c_abi_x64.c b/src/compiler/abi/c_abi_x64.c index 70f84edb9..7a0341722 100644 --- a/src/compiler/abi/c_abi_x64.c +++ b/src/compiler/abi/c_abi_x64.c @@ -60,9 +60,9 @@ static bool x64_type_is_illegal_vector(Type *type) if (type->type_kind != TYPE_VECTOR) return false; ByteSize size = type_size(type); // Less than 64 bits or larger than the avx native size => not allowed. - if (size <= 8 || size > platform_target.x64.native_vector_size_avx) return true; + if (size <= 8 || size > compiler.platform.x64.native_vector_size_avx) return true; // If we pass i128 in mem, then check for that. - if (platform_target.x64.pass_int128_vector_in_mem) + if (compiler.platform.x64.pass_int128_vector_in_mem) { // Illegal if i128/u128 TypeKind kind = type->array.base->type_kind; @@ -242,7 +242,7 @@ void x64_classify_struct_union(Type *type, ByteSize offset_base, X64Class *curre // and fallback to memory. if (size > 16 && ((!is_union && size != type_size(member->type)) - || size > platform_target.x64.native_vector_size_avx)) + || size > compiler.platform.x64.native_vector_size_avx)) { *lo_class = CLASS_MEMORY; x64_classify_post_merge(size, lo_class, hi_class); @@ -287,7 +287,7 @@ void x64_classify_array(Type *type, ByteSize offset_base, X64Class *current, X64 // The only case a 256-bit or a 512-bit wide vector could be used is when // the struct contains a single 256-bit or 512-bit field. Early check // and fallback to memory. - if (size > 16 && (size != type_size(element) || size > platform_target.x64.native_vector_size_avx)) + if (size > 16 && (size != type_size(element) || size > compiler.platform.x64.native_vector_size_avx)) { *lo_class = CLASS_MEMORY; return; @@ -343,9 +343,9 @@ void x64_classify_vector(Type *type, ByteSize offset_base, X64Class *current, X6 } return; } - if (size == 16 || (named_arg == NAMED && size <= platform_target.x64.native_vector_size_avx)) + if (size == 16 || (named_arg == NAMED && size <= compiler.platform.x64.native_vector_size_avx)) { - if (platform_target.x64.pass_int128_vector_in_mem + if (compiler.platform.x64.pass_int128_vector_in_mem && size != 16 && type_is_int128(element)) return; *lo_class = CLASS_SSE; @@ -637,7 +637,7 @@ static AbiType x64_get_byte_vector_type(Type *type) if (type->type_kind == TYPE_VECTOR) { Type *element = type->array.base->canonical; - if (platform_target.x64.pass_int128_vector_in_mem && type_is_int128(element)) + if (compiler.platform.x64.pass_int128_vector_in_mem && type_is_int128(element)) { // Convert to u64 return abi_type_get(type_get_vector(type_ulong, type_size(type) / 8)); diff --git a/src/compiler/abi/c_abi_x86.c b/src/compiler/abi/c_abi_x86.c index 6d152d02c..68aabb3a5 100644 --- a/src/compiler/abi/c_abi_x86.c +++ b/src/compiler/abi/c_abi_x86.c @@ -54,7 +54,7 @@ static ABIArgInfo *x86_create_indirect_result(Regs *regs, Type *type, ByVal by_v if (regs->int_regs) { regs->int_regs--; - if (!platform_target.x86.is_mcu_api) info->attributes.by_reg = true; + if (!compiler.platform.x86.is_mcu_api) info->attributes.by_reg = true; } return info; } @@ -84,7 +84,7 @@ static ABIArgInfo *create_indirect_return_x86(Type *type, Regs *regs) if (!regs->int_regs) return info; // Consume a register for the return. regs->int_regs--; - if (platform_target.x86.is_mcu_api) return info; + if (compiler.platform.x86.is_mcu_api) return info; info->attributes.by_reg = true; return info; @@ -97,7 +97,7 @@ static bool x86_should_return_type_in_reg(Type *type) if (size > 8) return false; // Require power of two for everything except mcu. - if (!platform_target.x86.is_mcu_api && !is_power_of_two(size)) return false; + if (!compiler.platform.x86.is_mcu_api && !is_power_of_two(size)) return false; if (type->type_kind == TYPE_VECTOR) { @@ -259,7 +259,7 @@ static inline bool x86_can_expand_indirect_aggregate_arg(Type *type) static bool x86_try_use_free_regs(Regs *regs, Type *type) { // 1. Floats are not passed in regs on soft floats. - if (!platform_target.x86.use_soft_float && type_is_float(type)) return false; + if (!compiler.platform.x86.use_soft_float && type_is_float(type)) return false; ByteSize size = type_size(type); @@ -273,7 +273,7 @@ static bool x86_try_use_free_regs(Regs *regs, Type *type) // earlier parameters that are passed on the stack. Also, // it does not allow passing >8-byte structs in-register, // even if there are 3 free registers available. - if (platform_target.x86.is_mcu_api) + if (compiler.platform.x86.is_mcu_api) { // 4a. Just return if there are not enough registers. if (size_in_regs > regs->int_regs) return false; @@ -312,7 +312,7 @@ static bool x86_try_put_primitive_in_reg(CallABI call, Regs *regs, Type *type) if (!x86_try_use_free_regs(regs, type)) return false; // 2. On MCU, do not use the inreg attribute. - if (platform_target.x86.is_mcu_api) return false; + if (compiler.platform.x86.is_mcu_api) return false; return true; } @@ -401,7 +401,7 @@ static inline ABIArgInfo *x86_classify_aggregate(CallABI call, Regs *regs, Type info = abi_arg_new_direct_coerce_type(type_uint); } // Not in reg on MCU - if (!platform_target.x86.is_mcu_api) info->attributes.by_reg = true; + if (!compiler.platform.x86.is_mcu_api) info->attributes.by_reg = true; return info; } @@ -411,7 +411,7 @@ static inline ABIArgInfo *x86_classify_aggregate(CallABI call, Regs *regs, Type // optimizations. // Don't do this for the MCU if there are still free integer registers // (see X86_64 ABI for full explanation). - if (size <= 16 && (!platform_target.x86.is_mcu_api || !regs->int_regs) && + if (size <= 16 && (!compiler.platform.x86.is_mcu_api || !regs->int_regs) && x86_can_expand_indirect_aggregate_arg(type)) { return abi_arg_new_expand(); @@ -502,13 +502,13 @@ void c_abi_func_create_x86(FunctionPrototype *prototype) switch (prototype->call_abi) { case CALL_C: - regs.int_regs = platform_target.default_number_regs_x86; + regs.int_regs = compiler.platform.default_number_regs_x86; break; default: UNREACHABLE } // 3. Special case for MCU: - if (platform_target.x86.is_mcu_api) + if (compiler.platform.x86.is_mcu_api) { regs.float_regs = 0; regs.int_regs = 3; diff --git a/src/compiler/asm/x86.h b/src/compiler/asm/x86.h index cca705367..a09c8fe70 100644 --- a/src/compiler/asm/x86.h +++ b/src/compiler/asm/x86.h @@ -1,5 +1,4 @@ - typedef enum { X86_CC, diff --git a/src/compiler/asm_target.c b/src/compiler/asm_target.c index 112339b8f..00c644135 100644 --- a/src/compiler/asm_target.c +++ b/src/compiler/asm_target.c @@ -9,7 +9,8 @@ const Clobbers NO_CLOBBER = { .mask[0] = 0 }; -INLINE AsmInstruction *insert_instruction_named(const char *name) + +INLINE AsmInstruction *insert_instruction_named(PlatformTarget *target, const char *name) { TokenType token_type = TOKEN_IDENT; unsigned len = (unsigned)strlen(name); @@ -18,7 +19,7 @@ INLINE AsmInstruction *insert_instruction_named(const char *name) uint32_t slot = hash & ASM_INSTRUCTION_MASK; while (1) { - AsmInstruction *instr = &asm_target.instructions[slot]; + AsmInstruction *instr = &target->instructions[slot]; if (!instr->name) { instr->name = interned; @@ -26,7 +27,6 @@ INLINE AsmInstruction *insert_instruction_named(const char *name) } slot = (slot + 1) & ASM_INSTRUCTION_MASK; } - } INLINE AsmArgBits parse_bits(const char **desc) @@ -152,9 +152,9 @@ NEXT: } return arg_type; } -static inline void reg_instr_clob(const char *name, Clobbers mask, const char *args) +static inline void reg_instr_clob(PlatformTarget *target, const char *name, Clobbers mask, const char *args) { - AsmInstruction *instr = insert_instruction_named(name); + AsmInstruction *instr = insert_instruction_named(target, name); instr->mask = mask; unsigned param_count = 0; while (args && args[0] != 0) @@ -165,9 +165,9 @@ static inline void reg_instr_clob(const char *name, Clobbers mask, const char *a instr->param_count = param_count; } -static inline void reg_instr(const char *name, const char *args) +static inline void reg_instr(PlatformTarget *target, const char *name, const char *args) { - AsmInstruction *instr = insert_instruction_named(name); + AsmInstruction *instr = insert_instruction_named(target, name); instr->mask = NO_CLOBBER; int param_count = 0; while (args && args[0] != 0) @@ -178,7 +178,7 @@ static inline void reg_instr(const char *name, const char *args) instr->param_count = param_count; } -INLINE void reg_register(const char *name, AsmRegisterType reg_type, AsmArgBits bits, unsigned clobber_id) +INLINE void reg_register(PlatformTarget *target, const char *name, AsmRegisterType reg_type, AsmArgBits bits, unsigned clobber_id) { TokenType token_type = TOKEN_CT_IDENT; unsigned len = (unsigned)strlen(name); @@ -187,42 +187,42 @@ INLINE void reg_register(const char *name, AsmRegisterType reg_type, AsmArgBits uint32_t slot = hash & ASM_REGISTER_MASK; while (1) { - AsmRegister *reg = &asm_target.registers[slot]; + AsmRegister *reg = &target->registers[slot]; if (!reg->name) { *reg = (AsmRegister) { .name = interned, .type = reg_type, .bits = bits, .clobber_index = clobber_id }; - asm_target.register_count++; + target->register_count++; return; } slot = (slot + 1) & ASM_REGISTER_MASK; } } -INLINE void reg_register_list(const char **names, unsigned count, AsmRegisterType param, unsigned bitsize, unsigned first_clobber) +INLINE void reg_register_list(PlatformTarget *target, const char **names, unsigned count, AsmRegisterType param, unsigned bitsize, unsigned first_clobber) { - for (unsigned i = 0; i < count; i++) reg_register(names[i], param, bitsize, i + first_clobber); + for (unsigned i = 0; i < count; i++) reg_register(target, names[i], param, bitsize, i + first_clobber); } -AsmInstruction *asm_instr_by_name(const char *name) +AsmInstruction *asm_instr_by_name(PlatformTarget *target, const char *name) { uint32_t hash = ASM_PTR_HASH(name); uint32_t slot = hash & ASM_INSTRUCTION_MASK; while (1) { - AsmInstruction *inst = &asm_target.instructions[slot]; + AsmInstruction *inst = &target->instructions[slot]; if (inst->name == name) return inst; if (inst->name == NULL) return NULL; slot = (slot + 1) & ASM_INSTRUCTION_MASK; } } -AsmRegister *asm_reg_by_name(const char *name) +AsmRegister *asm_reg_by_name(PlatformTarget *target, const char *name) { uint32_t hash = ASM_PTR_HASH(name); uint32_t slot = hash & ASM_REGISTER_MASK; while (1) { - AsmRegister *reg = &asm_target.registers[slot]; + AsmRegister *reg = &target->registers[slot]; const char *reg_name = reg->name; if (reg_name == name) return reg; if (!reg_name) return NULL; @@ -231,233 +231,233 @@ AsmRegister *asm_reg_by_name(const char *name) } -static void init_asm_aarch64(void) +static void init_asm_aarch64(PlatformTarget *target) { // Clobbers cc_flag_mask = clobbers_make(AARCH64_CC, -1); - asm_target.clobber_name_list = Aarch64ClobberNames; - asm_target.extra_clobbers = NULL; - reg_instr("ldr", "w:r32/r64, mem"); // Could be separated - reg_instr("ldrb", "w:r32, mem"); - reg_instr("ldrsb", "w:r32/r64, mem"); - reg_instr("ldrh", "w:r32, mem"); - reg_instr("ldrsh", "w:r32/r64, mem"); - reg_instr("ldrsw", "w:r64, mem"); - reg_instr("ldp", "w:r32/r64, w:r32/r64, mem"); - reg_instr("ldpsw", "w:r32/r64, w:r32/r64, mem"); - reg_instr("str", "r32/r64, w:mem"); - reg_instr("strb", "r32/r64, w:mem"); - reg_instr("strh", "r32/r64, w:mem"); - reg_instr("stp", "r32/r64, r32/r64, w:mem"); - reg_instr("mov", "w:r32/r64, mem"); - reg_register_list(aarch64_quad_regs, 32, ASM_REG_INT, ARG_BITS_64, AARCH64_R0); - reg_register_list(aarch64_long_regs, 32, ASM_REG_INT, ARG_BITS_32, AARCH64_R0); - reg_register_list(aarch64_f128_regs, 32, ASM_REG_FLOAT, ARG_BITS_128, AARCH64_Q0); - reg_register_list(aarch64_double_regs, 32, ASM_REG_FLOAT, ARG_BITS_64, AARCH64_Q0); - reg_register_list(aarch64_float_regs, 32, ASM_REG_FLOAT, ARG_BITS_32, AARCH64_Q0); - reg_register_list(aarch64_f16_regs, 32, ASM_REG_FLOAT, ARG_BITS_16, AARCH64_Q0); - reg_register_list(aarch64_f8_regs, 32, ASM_REG_FLOAT, ARG_BITS_8, AARCH64_Q0); - reg_register_list(aarch64_v8b_regs, 32, ASM_REG_IVEC, ARG_BITS_64, AARCH64_FIRST_RV_CLOBBER); - reg_register_list(aarch64_v16b_regs, 32, ASM_REG_IVEC, ARG_BITS_128, AARCH64_FIRST_RV_CLOBBER); - reg_register_list(aarch64_v4h_regs, 32, ASM_REG_IVEC, ARG_BITS_64, AARCH64_FIRST_RV_CLOBBER); - reg_register_list(aarch64_v8h_regs, 32, ASM_REG_IVEC, ARG_BITS_128, AARCH64_FIRST_RV_CLOBBER); - reg_register_list(aarch64_v2s_regs, 32, ASM_REG_IVEC, ARG_BITS_64, AARCH64_FIRST_RV_CLOBBER); - reg_register_list(aarch64_v4s_regs, 32, ASM_REG_IVEC, ARG_BITS_128, AARCH64_FIRST_RV_CLOBBER); - reg_register_list(aarch64_v1d_regs, 32, ASM_REG_IVEC, ARG_BITS_64, AARCH64_FIRST_RV_CLOBBER); - reg_register_list(aarch64_v2d_regs, 32, ASM_REG_IVEC, ARG_BITS_128, AARCH64_FIRST_RV_CLOBBER); - reg_register("$sp", ASM_REG_INT, ARG_BITS_64, AARCH64_R31); + target->clobber_name_list = Aarch64ClobberNames; + target->extra_clobbers = NULL; + reg_instr(target, "ldr", "w:r32/r64, mem"); // Could be separated + reg_instr(target, "ldrb", "w:r32, mem"); + reg_instr(target, "ldrsb", "w:r32/r64, mem"); + reg_instr(target, "ldrh", "w:r32, mem"); + reg_instr(target, "ldrsh", "w:r32/r64, mem"); + reg_instr(target, "ldrsw", "w:r64, mem"); + reg_instr(target, "ldp", "w:r32/r64, w:r32/r64, mem"); + reg_instr(target, "ldpsw", "w:r32/r64, w:r32/r64, mem"); + reg_instr(target, "str", "r32/r64, w:mem"); + reg_instr(target, "strb", "r32/r64, w:mem"); + reg_instr(target, "strh", "r32/r64, w:mem"); + reg_instr(target, "stp", "r32/r64, r32/r64, w:mem"); + reg_instr(target, "mov", "w:r32/r64, mem"); + reg_register_list(target, aarch64_quad_regs, 32, ASM_REG_INT, ARG_BITS_64, AARCH64_R0); + reg_register_list(target, aarch64_long_regs, 32, ASM_REG_INT, ARG_BITS_32, AARCH64_R0); + reg_register_list(target, aarch64_f128_regs, 32, ASM_REG_FLOAT, ARG_BITS_128, AARCH64_Q0); + reg_register_list(target, aarch64_double_regs, 32, ASM_REG_FLOAT, ARG_BITS_64, AARCH64_Q0); + reg_register_list(target, aarch64_float_regs, 32, ASM_REG_FLOAT, ARG_BITS_32, AARCH64_Q0); + reg_register_list(target, aarch64_f16_regs, 32, ASM_REG_FLOAT, ARG_BITS_16, AARCH64_Q0); + reg_register_list(target, aarch64_f8_regs, 32, ASM_REG_FLOAT, ARG_BITS_8, AARCH64_Q0); + reg_register_list(target, aarch64_v8b_regs, 32, ASM_REG_IVEC, ARG_BITS_64, AARCH64_FIRST_RV_CLOBBER); + reg_register_list(target, aarch64_v16b_regs, 32, ASM_REG_IVEC, ARG_BITS_128, AARCH64_FIRST_RV_CLOBBER); + reg_register_list(target, aarch64_v4h_regs, 32, ASM_REG_IVEC, ARG_BITS_64, AARCH64_FIRST_RV_CLOBBER); + reg_register_list(target, aarch64_v8h_regs, 32, ASM_REG_IVEC, ARG_BITS_128, AARCH64_FIRST_RV_CLOBBER); + reg_register_list(target, aarch64_v2s_regs, 32, ASM_REG_IVEC, ARG_BITS_64, AARCH64_FIRST_RV_CLOBBER); + reg_register_list(target, aarch64_v4s_regs, 32, ASM_REG_IVEC, ARG_BITS_128, AARCH64_FIRST_RV_CLOBBER); + reg_register_list(target, aarch64_v1d_regs, 32, ASM_REG_IVEC, ARG_BITS_64, AARCH64_FIRST_RV_CLOBBER); + reg_register_list(target, aarch64_v2d_regs, 32, ASM_REG_IVEC, ARG_BITS_128, AARCH64_FIRST_RV_CLOBBER); + reg_register(target, "$sp", ASM_REG_INT, ARG_BITS_64, AARCH64_R31); } -static void init_asm_wasm(void) +static void init_asm_wasm(PlatformTarget *target) { error_exit("WASM asm not complete."); } -static void init_asm_arm(void) +static void init_asm_arm(PlatformTarget *target) { error_exit("ARM asm not complete."); } -static void init_asm_riscv(void) +static void init_asm_riscv(PlatformTarget *target) { error_exit("RISCV asm not complete."); } -static void init_asm_ppc(void) +static void init_asm_ppc(PlatformTarget *target) { error_exit("PPC asm not complete."); } -static void init_asm_x86(void) +static void init_asm_x86(PlatformTarget* target) { Clobbers rax_mask = clobbers_make(X86_RAX, -1); Clobbers cc_flag_mask = clobbers_make(X86_CC, -1); Clobbers rax_cc_mask = clobbers_make_from(cc_flag_mask, X86_RAX, -1); Clobbers rax_rdx_cc_mask = clobbers_make_from(cc_flag_mask, X86_RAX, X86_RDX, -1); - bool is_x64 = platform_target.arch == ARCH_TYPE_X86_64; + bool is_x64 = target->arch == ARCH_TYPE_X86_64; if (!is_x64) { - reg_instr_clob("aaa", rax_mask, 0); - reg_instr_clob("into", cc_flag_mask, NULL); - reg_instr("pushl", "r32/mem/imm32"); - reg_instr("popl", "w:r32/mem/imm32"); + reg_instr_clob(target, "aaa", rax_mask, 0); + reg_instr_clob(target, "into", cc_flag_mask, NULL); + reg_instr(target, "pushl", "r32/mem/imm32"); + reg_instr(target, "popl", "w:r32/mem/imm32"); } if (is_x64) { - reg_instr_clob("syscall", clobbers_make_from(cc_flag_mask, X86_RAX, X86_R11, X86_RCX, -1), NULL); - reg_instr("pushq", "r64/mem"); - reg_instr("popq", "w:r64/mem"); + reg_instr_clob(target, "syscall", clobbers_make_from(cc_flag_mask, X86_RAX, X86_R11, X86_RCX, -1), NULL); + reg_instr(target, "pushq", "r64/mem"); + reg_instr(target, "popq", "w:r64/mem"); } - reg_instr_clob("adcb", cc_flag_mask, "rw:r8/mem, r8/mem/imm8"); - reg_instr_clob("adcw", cc_flag_mask, "rw:r16/mem, r16/mem/imm16/immi8"); - reg_instr_clob("adcl", cc_flag_mask, "rw:r32/mem, r32/mem/imm32/immi8"); - reg_instr_clob("adcq", cc_flag_mask, "rw:r64/mem, r64/mem/immi32/immi8"); + reg_instr_clob(target, "adcb", cc_flag_mask, "rw:r8/mem, r8/mem/imm8"); + reg_instr_clob(target, "adcw", cc_flag_mask, "rw:r16/mem, r16/mem/imm16/immi8"); + reg_instr_clob(target, "adcl", cc_flag_mask, "rw:r32/mem, r32/mem/imm32/immi8"); + reg_instr_clob(target, "adcq", cc_flag_mask, "rw:r64/mem, r64/mem/immi32/immi8"); - reg_instr_clob("adcxl", cc_flag_mask, "r32, rw:r32/mem"); - reg_instr_clob("adcxq", cc_flag_mask, "r64, rw:r64/mem"); + reg_instr_clob(target, "adcxl", cc_flag_mask, "r32, rw:r32/mem"); + reg_instr_clob(target, "adcxq", cc_flag_mask, "r64, rw:r64/mem"); - reg_instr_clob("addb", cc_flag_mask, "rw:r8/mem, r8/mem/imm8"); - reg_instr_clob("addw", cc_flag_mask, "rw:r16/mem, r16/mem/imm16/immi8"); - reg_instr_clob("addl", cc_flag_mask, "rw:r32/mem, r32/mem/imm32/immi8"); - reg_instr_clob("addq", cc_flag_mask, "rw:r64/mem, r64/mem/immi32/immi8"); + reg_instr_clob(target, "addb", cc_flag_mask, "rw:r8/mem, r8/mem/imm8"); + reg_instr_clob(target, "addw", cc_flag_mask, "rw:r16/mem, r16/mem/imm16/immi8"); + reg_instr_clob(target, "addl", cc_flag_mask, "rw:r32/mem, r32/mem/imm32/immi8"); + reg_instr_clob(target, "addq", cc_flag_mask, "rw:r64/mem, r64/mem/immi32/immi8"); - reg_instr("addpd", "rw:v128, v128/mem"); - reg_instr("addps", "rw:v128, v128/mem"); - reg_instr("addsd", "rw:v128, v128/mem"); - reg_instr("addss", "rw:v128, v128/mem"); - reg_instr("vaddpd", "w:v128/v256/v512, v128/v256/v512, v128/v256/v512/mem"); - reg_instr("vaddps", "w:v128/v256/v512, v128/v256/v512, v128/v256/v512/mem"); - reg_instr("vaddsd", "w:v128, v128, v128/mem"); - reg_instr("vaddss", "w:v128, v128, v128/mem"); + reg_instr(target, "addpd", "rw:v128, v128/mem"); + reg_instr(target, "addps", "rw:v128, v128/mem"); + reg_instr(target, "addsd", "rw:v128, v128/mem"); + reg_instr(target, "addss", "rw:v128, v128/mem"); + reg_instr(target, "vaddpd", "w:v128/v256/v512, v128/v256/v512, v128/v256/v512/mem"); + reg_instr(target, "vaddps", "w:v128/v256/v512, v128/v256/v512, v128/v256/v512/mem"); + reg_instr(target, "vaddsd", "w:v128, v128, v128/mem"); + reg_instr(target, "vaddss", "w:v128, v128, v128/mem"); - reg_instr_clob("cbtw", rax_mask, NULL); - reg_instr_clob("cwtl", rax_mask, NULL); - reg_instr_clob("cltq", rax_mask, NULL); - reg_instr_clob("clc", rax_mask, NULL); - reg_instr_clob("cld", rax_mask, NULL); - reg_instr("clflush", "mem"); - reg_instr("movb", "w:r8/mem, r8/mem/imm8"); - reg_instr("movsbw", "w:r16/mem, r8/mem"); - reg_instr("movzbw", "w:r16/mem, r8/mem"); - reg_instr("movsbl", "w:r32/mem, r8/mem"); - reg_instr("movzbl", "w:r32/mem, r8/mem"); - reg_instr("movsbq", "w:r64/mem, r8/mem"); - reg_instr("movzbq", "w:r64/mem, r8/mem"); - reg_instr("movw", "w:r16/mem, r16/mem/imm16"); // Add seg - reg_instr("movswl", "w:r32/mem, r16/mem"); - reg_instr("movzwl", "w:r32/mem, r16/mem"); - reg_instr("movswq", "w:r64/mem, r16/mem"); - reg_instr("movzwq", "w:r64/mem, r16/mem"); - reg_instr("movl", "w:r32/mem, r32/mem/imm32"); - reg_instr("movslq", "w:r64/mem, r32/mem"); - reg_instr("movzlq", "w:r64/mem, r32/mem"); - reg_instr("movq", "w:r64/mem, r64/mem/immi32/imm64"); // Seg + reg_instr_clob(target, "cbtw", rax_mask, NULL); + reg_instr_clob(target, "cwtl", rax_mask, NULL); + reg_instr_clob(target, "cltq", rax_mask, NULL); + reg_instr_clob(target, "clc", rax_mask, NULL); + reg_instr_clob(target, "cld", rax_mask, NULL); + reg_instr(target, "clflush", "mem"); + reg_instr(target, "movb", "w:r8/mem, r8/mem/imm8"); + reg_instr(target, "movsbw", "w:r16/mem, r8/mem"); + reg_instr(target, "movzbw", "w:r16/mem, r8/mem"); + reg_instr(target, "movsbl", "w:r32/mem, r8/mem"); + reg_instr(target, "movzbl", "w:r32/mem, r8/mem"); + reg_instr(target, "movsbq", "w:r64/mem, r8/mem"); + reg_instr(target, "movzbq", "w:r64/mem, r8/mem"); + reg_instr(target, "movw", "w:r16/mem, r16/mem/imm16"); // Add seg + reg_instr(target, "movswl", "w:r32/mem, r16/mem"); + reg_instr(target, "movzwl", "w:r32/mem, r16/mem"); + reg_instr(target, "movswq", "w:r64/mem, r16/mem"); + reg_instr(target, "movzwq", "w:r64/mem, r16/mem"); + reg_instr(target, "movl", "w:r32/mem, r32/mem/imm32"); + reg_instr(target, "movslq", "w:r64/mem, r32/mem"); + reg_instr(target, "movzlq", "w:r64/mem, r32/mem"); + reg_instr(target, "movq", "w:r64/mem, r64/mem/immi32/imm64"); // Seg //reg_instr("mov", "wAARG_SEG | AARG_W, AARG_R16 | AARG_R64, 0); // Seg /* reg_instr("movabsb", AARG_R8 | AARG_IMM64, AARG_R8 | AARG_IMM64, 0); // Missing segment reg_instr("movawsw", AARG_R16 | AARG_IMM64, AARG_R16 | AARG_IMM64, 0); // Missing segment reg_instr("movalsl", AARG_R32 | AARG_IMM64, AARG_R32 | AARG_IMM64, 0); // Missing segment reg_instr("movaqsq", AARG_R64 | AARG_IMM64, AARG_R64 | AARG_IMM64, 0); // Missing segment*/ - reg_instr("nop", NULL); - reg_instr("nopw", NULL); - reg_instr("nopl", NULL); - reg_instr_clob("orb", cc_flag_mask, "rw:r8/mem, r8/mem/imm8"); - reg_instr_clob("orw", cc_flag_mask, "rw:r16/mem, r16/mem/imm16"); - reg_instr_clob("orl", cc_flag_mask, "rw:r32/mem, r32/mem/imm32"); - reg_instr_clob("orq", cc_flag_mask, "rw:r64/mem, r64/mem/immi32/imm64"); - reg_instr_clob("negb", cc_flag_mask, "rw:r8/mem"); - reg_instr_clob("negw", cc_flag_mask, "rw:r16/mem"); - reg_instr_clob("negl", cc_flag_mask, "rw:r32/mem"); - reg_instr_clob("negq", cc_flag_mask, "rw:r64/mem"); - reg_instr("notb", "rw:r8/mem"); - reg_instr("notw", "rw:r16/mem"); - reg_instr("notl", "rw:r32/mem"); - reg_instr("notq", "rw:r64/mem"); - reg_instr_clob("xorb", cc_flag_mask, "rw:r8/mem, r8/mem/imm8"); - reg_instr_clob("xorw", cc_flag_mask, "rw:r16/mem, r16/mem/imm16"); - reg_instr_clob("xorl", cc_flag_mask, "rw:r32/mem, r32/mem/imm32"); - reg_instr_clob("xorq", cc_flag_mask, "rw:r64/mem, r64/mem/immi32/imm64"); - reg_instr_clob("mulb", rax_cc_mask, "r8/mem"); - reg_instr_clob("mulw", rax_rdx_cc_mask, "r16/mem"); - reg_instr_clob("mull", rax_rdx_cc_mask, "r32/mem"); - reg_instr_clob("mulq", rax_rdx_cc_mask, "rw:r64/mem"); - reg_instr_clob("subb", rax_cc_mask, "rw:r8/mem, r8/mem/imm8"); - reg_instr_clob("subw", rax_cc_mask, "rw:r16/mem, r16/mem/imm16"); - reg_instr_clob("subl", rax_cc_mask, "rw:r32/mem, r32/mem/imm32"); - reg_instr_clob("subq", rax_cc_mask, "rw:r64/mem, r64/mem/immi32/imm64"); - reg_instr_clob("cpuid", clobbers_make_from(cc_flag_mask, X86_RAX, X86_RBX, X86_RCX, X86_RDX, -1), NULL); - reg_instr("hlt", NULL); - reg_instr("in", "w:r8/r16/r32, r16/imm8"); // Actually ensure reg_al_ax and dx - reg_instr_clob("incb", cc_flag_mask, "rw:r8/mem"); - reg_instr_clob("incw", cc_flag_mask, "rw:r16/mem"); - reg_instr_clob("incl", cc_flag_mask, "rw:r32/mem"); - reg_instr_clob("incq", cc_flag_mask, "rw:r64/mem"); - reg_instr("insb", NULL); - reg_instr("insw", NULL); - reg_instr("insl", NULL); - reg_instr_clob("int", cc_flag_mask, "imm8"); - reg_instr_clob("int3", cc_flag_mask, NULL); - reg_instr_clob("int1", cc_flag_mask, NULL); - reg_instr("invd", NULL); - reg_instr("invpcid", "r32/r64, mem"); - reg_instr("invlpg", "w:mem"); - reg_instr("invlpga", "r32, r64"); // c, a check this one! - reg_instr("iret", NULL); - reg_instr("iretl", NULL); - reg_instr("iretw", NULL); - reg_instr("iretq", NULL); - reg_instr("rdtsc", NULL); - reg_instr("rdtscp", NULL); - reg_instr("ret", NULL); - reg_instr("push", "imm8"); - reg_instr("pushw", "r16/mem/imm16"); - reg_instr("popw", "w:r16/mem"); + reg_instr(target, "nop", NULL); + reg_instr(target, "nopw", NULL); + reg_instr(target, "nopl", NULL); + reg_instr_clob(target, "orb", cc_flag_mask, "rw:r8/mem, r8/mem/imm8"); + reg_instr_clob(target, "orw", cc_flag_mask, "rw:r16/mem, r16/mem/imm16"); + reg_instr_clob(target, "orl", cc_flag_mask, "rw:r32/mem, r32/mem/imm32"); + reg_instr_clob(target, "orq", cc_flag_mask, "rw:r64/mem, r64/mem/immi32/imm64"); + reg_instr_clob(target, "negb", cc_flag_mask, "rw:r8/mem"); + reg_instr_clob(target, "negw", cc_flag_mask, "rw:r16/mem"); + reg_instr_clob(target, "negl", cc_flag_mask, "rw:r32/mem"); + reg_instr_clob(target, "negq", cc_flag_mask, "rw:r64/mem"); + reg_instr(target, "notb", "rw:r8/mem"); + reg_instr(target, "notw", "rw:r16/mem"); + reg_instr(target, "notl", "rw:r32/mem"); + reg_instr(target, "notq", "rw:r64/mem"); + reg_instr_clob(target, "xorb", cc_flag_mask, "rw:r8/mem, r8/mem/imm8"); + reg_instr_clob(target, "xorw", cc_flag_mask, "rw:r16/mem, r16/mem/imm16"); + reg_instr_clob(target, "xorl", cc_flag_mask, "rw:r32/mem, r32/mem/imm32"); + reg_instr_clob(target, "xorq", cc_flag_mask, "rw:r64/mem, r64/mem/immi32/imm64"); + reg_instr_clob(target, "mulb", rax_cc_mask, "r8/mem"); + reg_instr_clob(target, "mulw", rax_rdx_cc_mask, "r16/mem"); + reg_instr_clob(target, "mull", rax_rdx_cc_mask, "r32/mem"); + reg_instr_clob(target, "mulq", rax_rdx_cc_mask, "rw:r64/mem"); + reg_instr_clob(target, "subb", rax_cc_mask, "rw:r8/mem, r8/mem/imm8"); + reg_instr_clob(target, "subw", rax_cc_mask, "rw:r16/mem, r16/mem/imm16"); + reg_instr_clob(target, "subl", rax_cc_mask, "rw:r32/mem, r32/mem/imm32"); + reg_instr_clob(target, "subq", rax_cc_mask, "rw:r64/mem, r64/mem/immi32/imm64"); + reg_instr_clob(target, "cpuid", clobbers_make_from(cc_flag_mask, X86_RAX, X86_RBX, X86_RCX, X86_RDX, -1), NULL); + reg_instr(target, "hlt", NULL); + reg_instr(target, "in", "w:r8/r16/r32, r16/imm8"); // Actually ensure reg_al_ax and dx + reg_instr_clob(target, "incb", cc_flag_mask, "rw:r8/mem"); + reg_instr_clob(target, "incw", cc_flag_mask, "rw:r16/mem"); + reg_instr_clob(target, "incl", cc_flag_mask, "rw:r32/mem"); + reg_instr_clob(target, "incq", cc_flag_mask, "rw:r64/mem"); + reg_instr(target, "insb", NULL); + reg_instr(target, "insw", NULL); + reg_instr(target, "insl", NULL); + reg_instr_clob(target, "int", cc_flag_mask, "imm8"); + reg_instr_clob(target, "int3", cc_flag_mask, NULL); + reg_instr_clob(target, "int1", cc_flag_mask, NULL); + reg_instr(target, "invd", NULL); + reg_instr(target, "invpcid", "r32/r64, mem"); + reg_instr(target, "invlpg", "w:mem"); + reg_instr(target, "invlpga", "r32, r64"); // c, a check this one! + reg_instr(target, "iret", NULL); + reg_instr(target, "iretl", NULL); + reg_instr(target, "iretw", NULL); + reg_instr(target, "iretq", NULL); + reg_instr(target, "rdtsc", NULL); + reg_instr(target, "rdtscp", NULL); + reg_instr(target, "ret", NULL); + reg_instr(target, "push", "imm8"); + reg_instr(target, "pushw", "r16/mem/imm16"); + reg_instr(target, "popw", "w:r16/mem"); - asm_target.clobber_name_list = X86ClobberNames; - asm_target.extra_clobbers = "~{flags},~{dirflag},~{fspr}"; - if (platform_target.arch == ARCH_TYPE_X86) + target->clobber_name_list = X86ClobberNames; + target->extra_clobbers = "~{flags},~{dirflag},~{fspr}"; + if (target->arch == ARCH_TYPE_X86) { - reg_register_list(x86_long_regs, 8, ASM_REG_INT, ARG_BITS_32, X86_RAX); - reg_register_list(x86_word_regs, 8, ASM_REG_INT, ARG_BITS_16, X86_RAX); - reg_register_list(x86_low_byte_regs, 8, ASM_REG_INT, ARG_BITS_8, X86_RAX); - reg_register_list(x86_float_regs, 8, ASM_REG_FLOAT, ARG_BITS_80, X86_ST0); - reg_register_list(x86_xmm_regs, 8, ASM_REF_FVEC, ARG_BITS_128, X86_MM0); + reg_register_list(target, x86_long_regs, 8, ASM_REG_INT, ARG_BITS_32, X86_RAX); + reg_register_list(target, x86_word_regs, 8, ASM_REG_INT, ARG_BITS_16, X86_RAX); + reg_register_list(target, x86_low_byte_regs, 8, ASM_REG_INT, ARG_BITS_8, X86_RAX); + reg_register_list(target, x86_float_regs, 8, ASM_REG_FLOAT, ARG_BITS_80, X86_ST0); + reg_register_list(target, x86_xmm_regs, 8, ASM_REF_FVEC, ARG_BITS_128, X86_MM0); } else { - reg_register_list(x64_quad_regs, 15, ASM_REG_INT, ARG_BITS_64, X86_RAX); - reg_register_list(x86_long_regs, 15, ASM_REG_INT, ARG_BITS_32, X86_RAX); - reg_register_list(x86_word_regs, 15, ASM_REG_INT, ARG_BITS_16, X86_RAX); - reg_register_list(x86_low_byte_regs, 15, ASM_REG_INT, ARG_BITS_8, X86_RAX); - reg_register_list(x86_high_byte_regs, 4, ASM_REG_INT, ARG_BITS_8, X86_RAX); - reg_register_list(x86_xmm_regs, 16, ASM_REF_FVEC, ARG_BITS_128, X86_XMM0); - reg_register_list(x86_ymm_regs, 16, ASM_REF_FVEC, ARG_BITS_256, X86_XMM0); - reg_register_list(x86_zmm_regs, 16, ASM_REF_FVEC, ARG_BITS_512, X86_XMM0); + reg_register_list(target, x64_quad_regs, 15, ASM_REG_INT, ARG_BITS_64, X86_RAX); + reg_register_list(target, x86_long_regs, 15, ASM_REG_INT, ARG_BITS_32, X86_RAX); + reg_register_list(target, x86_word_regs, 15, ASM_REG_INT, ARG_BITS_16, X86_RAX); + reg_register_list(target, x86_low_byte_regs, 15, ASM_REG_INT, ARG_BITS_8, X86_RAX); + reg_register_list(target, x86_high_byte_regs, 4, ASM_REG_INT, ARG_BITS_8, X86_RAX); + reg_register_list(target, x86_xmm_regs, 16, ASM_REF_FVEC, ARG_BITS_128, X86_XMM0); + reg_register_list(target, x86_ymm_regs, 16, ASM_REF_FVEC, ARG_BITS_256, X86_XMM0); + reg_register_list(target, x86_zmm_regs, 16, ASM_REF_FVEC, ARG_BITS_512, X86_XMM0); } } -void init_asm(void) +void init_asm(PlatformTarget *target) { - if (asm_target.initialized) return; - asm_target.initialized = true; - switch (platform_target.arch) + if (target->asm_initialized) return; + target->asm_initialized = true; + switch (target->arch) { case ARCH_UNSUPPORTED: case ARCH_TYPE_X86_64: case ARCH_TYPE_X86: - init_asm_x86(); + init_asm_x86(target); return; case ARCH_TYPE_AARCH64: case ARCH_TYPE_AARCH64_BE: - init_asm_aarch64(); + init_asm_aarch64(target); return; case ARCH_TYPE_ARM: case ARCH_TYPE_ARMB: case ARCH_TYPE_THUMB: case ARCH_TYPE_THUMBEB: - init_asm_arm(); + init_asm_arm(target); return; case ARCH_TYPE_WASM64: case ARCH_TYPE_WASM32: - init_asm_wasm(); + init_asm_wasm(target); return; case ARCH_TYPE_XTENSA: error_exit("Xtensa asm support not yet available."); @@ -467,11 +467,11 @@ void init_asm(void) case ARCH_TYPE_PPC: case ARCH_TYPE_PPC64: case ARCH_TYPE_PPC64LE: - init_asm_ppc(); + init_asm_ppc(target); return; case ARCH_TYPE_RISCV32: case ARCH_TYPE_RISCV64: - init_asm_riscv(); + init_asm_riscv(target); return; } UNREACHABLE diff --git a/src/compiler/ast.c b/src/compiler/ast.c index 50df5c2e5..0628c7724 100644 --- a/src/compiler/ast.c +++ b/src/compiler/ast.c @@ -297,14 +297,14 @@ void decl_append_links_to_global(Decl *decl) CompilationUnit *unit = decl->unit; if (unit && unit->links) { - FOREACH(const char *, link, unit->links) global_context_add_link(link); + FOREACH(const char *, link, unit->links) linking_add_link(&compiler.linking, link); unit->links = NULL; // Don't register twice } if (decl->attrs_resolved && decl->attrs_resolved->links) { FOREACH(const char *, link, decl->attrs_resolved->links) { - global_context_add_link(link); + linking_add_link(&compiler.linking, link); } } } diff --git a/src/compiler/codegen_asm.c b/src/compiler/codegen_asm.c index 561b39a2d..363c3c7de 100644 --- a/src/compiler/codegen_asm.c +++ b/src/compiler/codegen_asm.c @@ -166,11 +166,11 @@ const char *codegen_create_asm(Ast *ast) assert(ast->ast_kind == AST_ASM_BLOCK_STMT); scratch_buffer_clear(); AsmInlineBlock *block = ast->asm_block_stmt.block; - if (platform_target.arch == ARCH_TYPE_X86_64 || platform_target.arch == ARCH_TYPE_X86) + if (compiler.platform.arch == ARCH_TYPE_X86_64 || compiler.platform.arch == ARCH_TYPE_X86) { return codegen_create_x86_att_asm(block); } - if (platform_target.arch == ARCH_TYPE_AARCH64) + if (compiler.platform.arch == ARCH_TYPE_AARCH64) { return codegen_create_aarch64_asm(block); } diff --git a/src/compiler/codegen_general.c b/src/compiler/codegen_general.c index c4de8d681..8eda44429 100644 --- a/src/compiler/codegen_general.c +++ b/src/compiler/codegen_general.c @@ -45,17 +45,17 @@ Type *type_abi_find_single_struct_element(Type *type) bool type_is_homogenous_base_type(Type *type) { type = type->canonical; - switch (platform_target.abi) + switch (compiler.platform.abi) { case ABI_PPC64_SVR4: switch (type->type_kind) { case TYPE_F128: - if (!platform_target.float128) return false; + if (!compiler.platform.float128) return false; FALLTHROUGH; case TYPE_F32: case TYPE_F64: - return !platform_target.ppc64.is_softfp; + return !compiler.platform.ppc64.is_softfp; case TYPE_VECTOR: return type_size(type) == 128 / 8; default: @@ -134,10 +134,10 @@ bool type_is_homogenous_base_type(Type *type) bool type_homogenous_aggregate_small_enough(Type *type, unsigned members) { - switch (platform_target.abi) + switch (compiler.platform.abi) { case ABI_PPC64_SVR4: - if (type->type_kind == TYPE_F128 && platform_target.float128) return members <= 8; + if (type->type_kind == TYPE_F128 && compiler.platform.float128) return members <= 8; if (type->type_kind == TYPE_VECTOR) return members <= 8; // Use max 8 registers. return ((type_size(type) + 7) / 8) * members <= 8; @@ -279,7 +279,7 @@ bool type_is_homogenous_aggregate(Type *type, Type **base, unsigned *elements) AlignSize type_alloca_alignment(Type *type) { AlignSize align = type_abi_alignment(type); - if (align < 16 && (platform_target.abi == ABI_X64 || platform_target.abi == ABI_WIN64)) + if (align < 16 && (compiler.platform.abi == ABI_X64 || compiler.platform.abi == ABI_WIN64)) { type = type_flatten(type); if (type->type_kind == TYPE_ARRAY && type_size(type) >= 16) return 16; @@ -291,13 +291,13 @@ AlignSize type_alloca_alignment(Type *type) void codegen_setup_object_names(Module *module, const char **ir_filename, const char **asm_filename, const char **object_filename) { const char *result = module_create_object_file_name(module); - *ir_filename = str_printf(active_target.backend == BACKEND_LLVM ? "%s.ll" : "%s.ir", result); - if (active_target.ir_file_dir) *ir_filename = file_append_path(active_target.ir_file_dir, *ir_filename); + *ir_filename = str_printf(compiler.build.backend == BACKEND_LLVM ? "%s.ll" : "%s.ir", result); + if (compiler.build.ir_file_dir) *ir_filename = file_append_path(compiler.build.ir_file_dir, *ir_filename); *object_filename = str_printf("%s%s", result, get_object_extension()); - if (active_target.emit_asm) + if (compiler.build.emit_asm) { *asm_filename = str_printf("%s.s", result); - if (active_target.asm_file_dir) *asm_filename = file_append_path(active_target.asm_file_dir, *asm_filename); + if (compiler.build.asm_file_dir) *asm_filename = file_append_path(compiler.build.asm_file_dir, *asm_filename); } - if (active_target.object_file_dir) *object_filename = file_append_path(active_target.object_file_dir, *object_filename); + if (compiler.build.object_file_dir) *object_filename = file_append_path(compiler.build.object_file_dir, *object_filename); } diff --git a/src/compiler/codegen_internal.h b/src/compiler/codegen_internal.h index 21a6d499f..e72dcbc5f 100644 --- a/src/compiler/codegen_internal.h +++ b/src/compiler/codegen_internal.h @@ -112,10 +112,10 @@ UNUSED static inline bool abi_type_is_promotable_integer_or_bool(AbiType type) { if (!type_is_integer_or_bool_kind(type.type)) return false; if (type.type == type_bool) return true; - return type.type->builtin.bitsize < platform_target.width_c_int; + return type.type->builtin.bitsize < compiler.platform.width_c_int; } // We should only get npot or > big ints here. - assert(!is_power_of_two(type.int_bits_plus_1 - 1) || type.int_bits_plus_1 < platform_target.width_c_int); + assert(!is_power_of_two(type.int_bits_plus_1 - 1) || type.int_bits_plus_1 < compiler.platform.width_c_int); return false; } diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 58cf0bd7c..b7b5ed16f 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -13,21 +13,19 @@ #define MAX_OUTPUT_FILES 1000000 #define MAX_MODULES 100000 -GlobalContext global_context; -BuildTarget active_target; -AsmTarget asm_target; +CompilerState compiler; Vmem ast_arena; Vmem expr_arena; Vmem decl_arena; Vmem type_info_arena; -double compiler_init_time; -double compiler_parsing_time; -double compiler_sema_time; -double compiler_ir_gen_time; -double compiler_codegen_time; -double compiler_link_time; +static double compiler_init_time; +static double compiler_parsing_time; +static double compiler_sema_time; +static double compiler_ir_gen_time; +static double compiler_codegen_time; +static double compiler_link_time; const char* c3_suffix_list[3] = { ".c3", ".c3t", ".c3i" }; @@ -43,19 +41,19 @@ void compiler_init(BuildOptions *build_options) INFO_LOG("Version: %s", COMPILER_VERSION); - global_context = (GlobalContext ){ .in_panic_mode = false }; + compiler = (CompilerState) { .context.in_panic_mode = false }; // Skip library detection. //compiler.lib_dir = find_lib_dir(); //DEBUG_LOG("Found std library: %s", compiler.lib_dir); - htable_init(&global_context.modules, 16 * 1024); - decltable_init(&global_context.symbols, INITIAL_SYMBOL_MAP); - decltable_init(&global_context.generic_symbols, INITIAL_GENERIC_SYMBOL_MAP); + htable_init(&compiler.context.modules, 16 * 1024); + decltable_init(&compiler.context.symbols, INITIAL_SYMBOL_MAP); + decltable_init(&compiler.context.generic_symbols, INITIAL_GENERIC_SYMBOL_MAP); - htable_init(&global_context.features, 1024); - htable_init(&global_context.compiler_defines, 16 * 1024); - global_context.module_list = NULL; - global_context.generic_module_list = NULL; - global_context.method_extensions = NULL; + htable_init(&compiler.context.features, 1024); + htable_init(&compiler.context.compiler_defines, 16 * 1024); + compiler.context.module_list = NULL; + compiler.context.generic_module_list = NULL; + compiler.context.method_extensions = NULL; vmem_init(&ast_arena, 512); ast_calloc(); vmem_init(&expr_arena, 512); @@ -67,17 +65,17 @@ void compiler_init(BuildOptions *build_options) // Create zero index value. if (build_options->std_lib_dir) { - global_context.lib_dir = build_options->std_lib_dir; + compiler.context.lib_dir = build_options->std_lib_dir; } else { - global_context.lib_dir = find_lib_dir(); + compiler.context.lib_dir = find_lib_dir(); } } static void compiler_lex(void) { - FOREACH(const char *, source, global_context.sources) + FOREACH(const char *, source, compiler.context.sources) { bool loaded = false; const char *error; @@ -134,14 +132,14 @@ void **tilde_gen(Module** modules, unsigned module_count) const char *build_base_name(void) { const char *name; - if (active_target.name) + if (compiler.build.name) { - name = active_target.name; + name = compiler.build.name; } else { - Module **modules = global_context.module_list; - Module *main_module = (modules[0] == global_context.core_module && vec_size(modules) > 1) ? modules[1] : modules[0]; + Module **modules = compiler.context.module_list; + Module *main_module = (modules[0] == compiler.context.core_module && vec_size(modules) > 1) ? modules[1] : modules[0]; Path *path = main_module->name; size_t first = 0; for (size_t i = path->len; i > 0; i--) @@ -159,15 +157,15 @@ const char *build_base_name(void) static const char *exe_name(void) { - assert(global_context.main || active_target.no_entry); + assert(compiler.context.main || compiler.build.no_entry); const char *name; - if (active_target.name || active_target.no_entry) + if (compiler.build.name || compiler.build.no_entry) { - name = active_target.name ? active_target.name : "out"; + name = compiler.build.name ? compiler.build.name : "out"; } else { - Path *path = global_context.main->unit->module->name; + Path *path = compiler.context.main->unit->module->name; size_t first = 0; for (size_t i = path->len; i > 0; i--) { @@ -179,14 +177,14 @@ static const char *exe_name(void) } name = &path->module[first]; } - switch (active_target.arch_os_target) + switch (compiler.build.arch_os_target) { case WINDOWS_AARCH64: case WINDOWS_X64: case MINGW_X64: return str_cat(name, ".exe"); default: - if (arch_is_wasm(platform_target.arch)) return str_cat(name, ".wasm"); + if (arch_is_wasm(compiler.platform.arch)) return str_cat(name, ".wasm"); return name; } } @@ -194,7 +192,7 @@ static const char *exe_name(void) static const char *dynamic_lib_name(void) { const char *name = build_base_name(); - switch (active_target.arch_os_target) + switch (compiler.build.arch_os_target) { case WINDOWS_AARCH64: case WINDOWS_X64: @@ -211,7 +209,7 @@ static const char *dynamic_lib_name(void) static const char *static_lib_name(void) { const char *name = build_base_name(); - switch (active_target.arch_os_target) + switch (compiler.build.arch_os_target) { case WINDOWS_AARCH64: case WINDOWS_X64: @@ -297,9 +295,9 @@ static void compiler_print_bench(void) if (compiler_codegen_time >= 0) { last = compiler_codegen_time; - if (active_target.build_threads > 1) + if (compiler.build.build_threads > 1) { - printf("Codegen took: %10.3f ms %8.1f %% (%d threads)\n", codegen_time * 1000, codegen_time * 100 / last, active_target.build_threads); + printf("Codegen took: %10.3f ms %8.1f %% (%d threads)\n", codegen_time * 1000, codegen_time * 100 / last, compiler.build.build_threads); } else { @@ -336,18 +334,18 @@ void compiler_parse(void) global_context_clear_errors(); // Add the standard library - if (global_context.lib_dir && !no_stdlib()) + if (compiler.context.lib_dir && !no_stdlib()) { - file_add_wildcard_files(&global_context.sources, global_context.lib_dir, true, c3_suffix_list, 3); + file_add_wildcard_files(&compiler.context.sources, compiler.context.lib_dir, true, c3_suffix_list, 3); } // Load and parse all files. bool has_error = false; - if (active_target.print_input) + if (compiler.build.print_input) { puts("# input-files-begin"); } - FOREACH(const char *, source, global_context.sources) + FOREACH(const char *, source, compiler.context.sources) { bool loaded = false; const char *error; @@ -355,13 +353,13 @@ void compiler_parse(void) if (!file) error_exit(error); if (loaded) continue; if (!parse_file(file)) has_error = true; - if (active_target.print_input) puts(file->full_path); + if (compiler.build.print_input) puts(file->full_path); } - if (active_target.print_input) + if (compiler.build.print_input) { puts("# input-files-end"); } - if (active_target.read_stdin) + if (compiler.build.read_stdin) { if (!parse_stdin()) has_error = true; } @@ -382,8 +380,8 @@ static void create_output_dir(const char *dir) void compiler_compile(void) { sema_analysis_run(); - - Module **modules = global_context.module_list; + compiler_sema_time = bench_mark(); + Module **modules = compiler.context.module_list; unsigned module_count = vec_size(modules); if (module_count > MAX_MODULES) { @@ -394,12 +392,12 @@ void compiler_compile(void) error_exit("No module to compile."); } - if (active_target.output_headers) + if (compiler.build.output_headers) { header_gen(modules, module_count); } - if (active_target.check_only) + if (compiler.build.check_only) { free_arenas(); return; @@ -408,35 +406,35 @@ void compiler_compile(void) void **gen_contexts; void (*task)(void *); - if (active_target.asm_file_dir || active_target.ir_file_dir || active_target.emit_object_files) + if (compiler.build.asm_file_dir || compiler.build.ir_file_dir || compiler.build.emit_object_files) { - if (active_target.build_dir && !file_exists(active_target.build_dir) && !dir_make(active_target.build_dir)) + if (compiler.build.build_dir && !file_exists(compiler.build.build_dir) && !dir_make(compiler.build.build_dir)) { - error_exit("Failed to create build directory '%s'.", active_target.build_dir); + error_exit("Failed to create build directory '%s'.", compiler.build.build_dir); } } - if (active_target.ir_file_dir && active_target.emit_llvm) + if (compiler.build.ir_file_dir && compiler.build.emit_llvm) { - if (!file_exists(active_target.ir_file_dir) && !dir_make(active_target.ir_file_dir)) + if (!file_exists(compiler.build.ir_file_dir) && !dir_make(compiler.build.ir_file_dir)) { - error_exit("Failed to create output directory '%s'.", active_target.ir_file_dir); + error_exit("Failed to create output directory '%s'.", compiler.build.ir_file_dir); } } - if (active_target.asm_file_dir && active_target.emit_asm) + if (compiler.build.asm_file_dir && compiler.build.emit_asm) { - if (!file_exists(active_target.asm_file_dir) && !dir_make(active_target.asm_file_dir)) + if (!file_exists(compiler.build.asm_file_dir) && !dir_make(compiler.build.asm_file_dir)) { - error_exit("Failed to create output directory '%s'.", active_target.asm_file_dir); + error_exit("Failed to create output directory '%s'.", compiler.build.asm_file_dir); } } - if (active_target.object_file_dir && active_target.emit_object_files) + if (compiler.build.object_file_dir && compiler.build.emit_object_files) { - if (!file_exists(active_target.object_file_dir) && !dir_make(active_target.object_file_dir)) + if (!file_exists(compiler.build.object_file_dir) && !dir_make(compiler.build.object_file_dir)) { - error_exit("Failed to create output directory '%s'.", active_target.object_file_dir); + error_exit("Failed to create output directory '%s'.", compiler.build.object_file_dir); } } - if (active_target.type == TARGET_TYPE_EXECUTABLE && !global_context.main && !active_target.no_entry) + if (compiler.build.type == TARGET_TYPE_EXECUTABLE && !compiler.context.main && !compiler.build.no_entry) { error_exit("The 'main' function for the executable could not found, did you forget to add it?\n\n" "- If you're using an alternative entry point you can suppress this message using '--no-entry'.\n" @@ -444,7 +442,7 @@ void compiler_compile(void) "- If you just want to output object files for later linking, use 'compile-only'."); } - switch (active_target.backend) + switch (compiler.build.backend) { case BACKEND_LLVM: gen_contexts = llvm_gen(modules, module_count); @@ -462,20 +460,20 @@ void compiler_compile(void) const char *output_exe = NULL; const char *output_static = NULL; const char *output_dynamic = NULL; - if (!active_target.test_output && !active_target.benchmark_output) + if (!compiler.build.test_output && !compiler.build.benchmark_output) { - switch (active_target.type) + switch (compiler.build.type) { case TARGET_TYPE_BENCHMARK: - active_target.name = "benchmarkrun"; + compiler.build.name = "benchmarkrun"; output_exe = exe_name(); break; case TARGET_TYPE_TEST: - active_target.name = "testrun"; + compiler.build.name = "testrun"; output_exe = exe_name(); break; case TARGET_TYPE_EXECUTABLE: - assert(global_context.main || active_target.no_entry); + assert(compiler.context.main || compiler.build.no_entry); output_exe = exe_name(); break; case TARGET_TYPE_STATIC_LIB: @@ -494,9 +492,9 @@ void compiler_compile(void) free_arenas(); uint32_t output_file_count = vec_size(gen_contexts); - unsigned cfiles = vec_size(active_target.csources); + unsigned cfiles = vec_size(compiler.build.csources); unsigned cfiles_library = 0; - FOREACH(LibraryTarget *, lib, active_target.ccompiling_libraries) + FOREACH(LibraryTarget *, lib, compiler.build.ccompiling_libraries) { cfiles_library += vec_size(lib->csources); } @@ -514,15 +512,15 @@ void compiler_compile(void) if (cfiles) { - int compiled = compile_cfiles(active_target.cc, active_target.csources, - active_target.cflags, active_target.cinclude_dirs, &obj_files[output_file_count], "tmp_c_compile"); + int compiled = compile_cfiles(compiler.build.cc, compiler.build.csources, + compiler.build.cflags, compiler.build.cinclude_dirs, &obj_files[output_file_count], "tmp_c_compile"); assert(cfiles == compiled); (void)compiled; } const char **obj_file_next = &obj_files[output_file_count + cfiles]; - FOREACH(LibraryTarget *, lib, active_target.ccompiling_libraries) + FOREACH(LibraryTarget *, lib, compiler.build.ccompiling_libraries) { - obj_file_next += compile_cfiles(lib->cc ? lib->cc : active_target.cc, lib->csources, + obj_file_next += compile_cfiles(lib->cc ? lib->cc : compiler.build.cc, lib->csources, lib->cflags, lib->cinclude_dirs, obj_file_next, lib->parent->provides); } @@ -535,7 +533,7 @@ void compiler_compile(void) } #if USE_PTHREAD - INFO_LOG("Will use %d thread(s).\n", active_target.build_threads); + INFO_LOG("Will use %d thread(s).\n", compiler.build.build_threads); #endif unsigned task_count = vec_size(tasks); if (task_count == 1) @@ -544,23 +542,23 @@ void compiler_compile(void) } else if (task_count > 1) { - taskqueue_run(active_target.build_threads > task_count ? task_count : active_target.build_threads, tasks); + taskqueue_run(compiler.build.build_threads > task_count ? task_count : compiler.build.build_threads, tasks); } - if (active_target.print_output) + if (compiler.build.print_output) { puts("# output-files-begin"); } for (unsigned i = 0; i < output_file_count; i++) { obj_files[i] = compile_data[i].object_name; - if (active_target.print_output) + if (compiler.build.print_output) { puts(obj_files[i]); } assert(obj_files[i] || !output_exe); } - if (active_target.print_output) + if (compiler.build.print_output) { puts("# output-files-end"); } @@ -571,19 +569,19 @@ void compiler_compile(void) if (output_exe) { - if (active_target.output_dir) + if (compiler.build.output_dir) { - create_output_dir(active_target.output_dir); - output_exe = file_append_path(active_target.output_dir, output_exe); + create_output_dir(compiler.build.output_dir); + output_exe = file_append_path(compiler.build.output_dir, output_exe); } if (file_is_dir(output_exe)) { error_exit("Cannot create exe with the name '%s' - there is already a directory with that name.", output_exe); } - bool system_linker_available = link_libc() && platform_target.os != OS_TYPE_WIN32; - bool use_system_linker = system_linker_available && active_target.arch_os_target == default_target; - switch (active_target.linker_type) + bool system_linker_available = link_libc() && compiler.platform.os != OS_TYPE_WIN32; + bool use_system_linker = system_linker_available && compiler.build.arch_os_target == default_target; + switch (compiler.build.linker_type) { case LINKER_TYPE_CC: if (!system_linker_available) @@ -599,7 +597,7 @@ void compiler_compile(void) default: break; } - if (use_system_linker || active_target.linker_type == LINKER_TYPE_CC) + if (use_system_linker || compiler.build.linker_type == LINKER_TYPE_CC) { platform_linker(output_exe, obj_files, output_file_count); compiler_link_time = bench_mark(); @@ -609,11 +607,11 @@ void compiler_compile(void) else { compiler_print_bench(); - if (!obj_format_linking_supported(platform_target.object_format) || !linker(output_exe, obj_files, + if (!obj_format_linking_supported(compiler.platform.object_format) || !linker(output_exe, obj_files, output_file_count)) { eprintf("No linking is performed due to missing linker support.\n"); - active_target.run_after_compile = false; + compiler.build.run_after_compile = false; } else { @@ -621,13 +619,13 @@ void compiler_compile(void) } } - if (active_target.run_after_compile) + if (compiler.build.run_after_compile) { DEBUG_LOG("Will run"); const char *name = output_exe; while (name[0] == '.' && name[1] == '/') name += 2; scratch_buffer_clear(); - if (platform_target.os == OS_TYPE_WIN32) + if (compiler.platform.os == OS_TYPE_WIN32) { size_t len = strlen(name); for (unsigned i = 0; i < len; i++) @@ -652,13 +650,13 @@ void compiler_compile(void) } name = scratch_buffer_to_string(); printf("Launching %s", name); - for (uint32_t i = 0; i < vec_size(active_target.args); ++i) { - printf(" %s", active_target.args[i]); + for (uint32_t i = 0; i < vec_size(compiler.build.args); ++i) { + printf(" %s", compiler.build.args[i]); } printf("\n"); - int ret = run_subprocess(name, active_target.args); - if (active_target.delete_after_run) + int ret = run_subprocess(name, compiler.build.args); + if (compiler.build.delete_after_run) { file_delete_file(name); } @@ -669,10 +667,10 @@ void compiler_compile(void) } else if (output_static) { - if (active_target.output_dir) + if (compiler.build.output_dir) { - create_output_dir(active_target.output_dir); - output_static = file_append_path(active_target.output_dir, output_static); + create_output_dir(compiler.build.output_dir); + output_static = file_append_path(compiler.build.output_dir, output_static); } if (file_is_dir(output_static)) { @@ -689,10 +687,10 @@ void compiler_compile(void) } else if (output_dynamic) { - if (active_target.output_dir) + if (compiler.build.output_dir) { - create_output_dir(active_target.output_dir); - output_dynamic = file_append_path(active_target.output_dir, output_dynamic); + create_output_dir(compiler.build.output_dir); + output_dynamic = file_append_path(compiler.build.output_dir, output_dynamic); } if (file_is_dir(output_dynamic)) { @@ -778,25 +776,25 @@ INLINE void expand_cinclude_dirs(const char *base_dir, const char **include_dirs void compile_target(BuildOptions *options) { - init_default_build_target(&active_target, options); + init_default_build_target(&compiler.build, options); compile(); } void clean_obj_files(void) { - file_delete_all_files_in_dir_with_suffix(active_target.ir_file_dir, ".ll"); - file_delete_all_files_in_dir_with_suffix(active_target.asm_file_dir, ".s"); - file_delete_all_files_in_dir_with_suffix(active_target.object_file_dir, ".obj"); - file_delete_all_files_in_dir_with_suffix(active_target.object_file_dir, ".o"); + file_delete_all_files_in_dir_with_suffix(compiler.build.ir_file_dir, ".ll"); + file_delete_all_files_in_dir_with_suffix(compiler.build.asm_file_dir, ".s"); + file_delete_all_files_in_dir_with_suffix(compiler.build.object_file_dir, ".obj"); + file_delete_all_files_in_dir_with_suffix(compiler.build.object_file_dir, ".o"); } void compile_clean(BuildOptions *options) { - init_build_target(&active_target, options); + init_build_target(&compiler.build, options); clean_obj_files(); } void compile_file_list(BuildOptions *options) { - init_build_target(&active_target, options); + init_build_target(&compiler.build, options); if (options->command == COMMAND_CLEAN_RUN) { clean_obj_files(); @@ -816,7 +814,7 @@ static void setup_int_define(const char *id, uint64_t i, Type *type) { error_exit("Integer define %s overflow.", id); } - void *previous = htable_set(&global_context.compiler_defines, (void*)id, expr); + void *previous = htable_set(&compiler.context.compiler_defines, (void*)id, expr); if (previous) { error_exit("Redefined ident %s", id); @@ -828,7 +826,7 @@ static void setup_bool_define(const char *id, bool value) TokenType token_type = TOKEN_CONST_IDENT; id = symtab_add(id, (uint32_t) strlen(id), fnv1a(id, (uint32_t) strlen(id)), &token_type); Expr *expr = expr_new_const_bool(INVALID_SPAN, type_bool, value); - void *previous = htable_set(&global_context.compiler_defines, (void *)id, expr); + void *previous = htable_set(&compiler.context.compiler_defines, (void *)id, expr); if (previous) { error_exit("Redefined ident %s", id); @@ -981,7 +979,7 @@ void print_syntax(BuildOptions *options) static int jump_buffer_size() { - switch (active_target.arch_os_target) + switch (compiler.build.arch_os_target) { case ARCH_OS_TARGET_DEFAULT: return 512; @@ -1038,22 +1036,22 @@ static int jump_buffer_size() static void execute_scripts(void) { - if (!vec_size(active_target.exec)) return; - if (active_target.trust_level < TRUST_FULL) + if (!vec_size(compiler.build.exec)) return; + if (compiler.build.trust_level < TRUST_FULL) { error_exit("This target has 'exec' directives, to run it trust level must be set to '--trust=full'."); } char *old_path = NULL; - if (active_target.script_dir) + if (compiler.build.script_dir) { old_path = getcwd(NULL, 0); - if (!dir_change(active_target.script_dir)) + if (!dir_change(compiler.build.script_dir)) { free(old_path); - error_exit("Failed to open script dir '%s'", active_target.script_dir); + error_exit("Failed to open script dir '%s'", compiler.build.script_dir); } } - FOREACH(const char *, exec, active_target.exec) + FOREACH(const char *, exec, compiler.build.exec) { StringSlice execs = slice_from_string(exec); StringSlice call = slice_next_token(&execs, ' '); @@ -1072,75 +1070,80 @@ static void execute_scripts(void) } void compile() { - symtab_init(active_target.symtab_size); - active_target.sources = target_expand_source_names(NULL, active_target.source_dirs, c3_suffix_list, 3, true); - expand_csources(NULL, active_target.csource_dirs, &active_target.csources); + symtab_init(compiler.build.symtab_size); + compiler.build.sources = target_expand_source_names(NULL, compiler.build.source_dirs, c3_suffix_list, 3, true); + if (compiler.build.testing) + { + const char **test_sources = target_expand_source_names(NULL, compiler.build.test_source_dirs, c3_suffix_list, 3, true); + FOREACH(const char *, file, test_sources) vec_add(compiler.build.sources, file); + } + expand_csources(NULL, compiler.build.csource_dirs, &compiler.build.csources); execute_scripts(); - global_context.main = NULL; - global_context.string_type = NULL; - asm_target.initialized = false; + compiler.context.main = NULL; + compiler.context.string_type = NULL; + compiler.platform.asm_initialized = false; // Create the core module if needed. Path *core_path = MALLOCS(Path); core_path->module = kw_std__core; core_path->span = INVALID_SPAN; core_path->len = strlen(kw_std__core); - global_context.core_module = compiler_find_or_create_module(core_path, NULL); + compiler.context.core_module = compiler_find_or_create_module(core_path, NULL); CompilationUnit *unit = CALLOCS(CompilationUnit); unit->file = source_file_generate("core_internal.c3"); - unit->module = global_context.core_module; - global_context.core_unit = unit; - target_setup(&active_target); - resolve_libraries(&active_target); - global_context.sources = active_target.sources; - FOREACH(LibraryTarget *, lib, active_target.ccompiling_libraries) + unit->module = compiler.context.core_module; + compiler.context.core_unit = unit; + target_setup(&compiler.build); + resolve_libraries(&compiler.build); + compiler.context.sources = compiler.build.sources; + FOREACH(LibraryTarget *, lib, compiler.build.ccompiling_libraries) { expand_csources(lib->parent->dir, lib->csource_dirs, &lib->csources); expand_cinclude_dirs(lib->parent->dir, lib->cinclude_dirs, &lib->cinclude_dirs); } TokenType type = TOKEN_CONST_IDENT; - FOREACH(const char *, feature_flag, active_target.feature_list) + FOREACH(const char *, feature_flag, compiler.build.feature_list) { feature_flag = symtab_preset(feature_flag, TOKEN_CONST_IDENT); - htable_set(&global_context.features, (void *) feature_flag, (void *) feature_flag); + htable_set(&compiler.context.features, (void *) feature_flag, (void *) feature_flag); } - setup_int_define("C_SHORT_SIZE", platform_target.width_c_short, type_int); - setup_int_define("C_INT_SIZE", platform_target.width_c_int, type_int); - setup_int_define("C_LONG_SIZE", platform_target.width_c_long, type_int); - setup_int_define("C_LONG_LONG_SIZE", platform_target.width_c_long_long, type_int); - setup_int_define("REGISTER_SIZE", platform_target.width_register, type_int); - setup_bool_define("C_CHAR_IS_SIGNED", platform_target.signed_c_char); - setup_bool_define("PLATFORM_BIG_ENDIAN", platform_target.big_endian); - setup_bool_define("PLATFORM_I128_SUPPORTED", platform_target.int128); - setup_bool_define("PLATFORM_F128_SUPPORTED", platform_target.float128); - setup_bool_define("PLATFORM_F16_SUPPORTED", platform_target.float16); - setup_int_define("ARCH_TYPE", (uint64_t)platform_target.arch, type_int); - setup_int_define("MEMORY_ENVIRONMENT", (uint64_t)active_target.memory_environment, type_int); + setup_int_define("C_SHORT_SIZE", compiler.platform.width_c_short, type_int); + setup_int_define("C_INT_SIZE", compiler.platform.width_c_int, type_int); + setup_int_define("C_LONG_SIZE", compiler.platform.width_c_long, type_int); + setup_int_define("C_LONG_LONG_SIZE", compiler.platform.width_c_long_long, type_int); + setup_int_define("REGISTER_SIZE", compiler.platform.width_register, type_int); + setup_bool_define("C_CHAR_IS_SIGNED", compiler.platform.signed_c_char); + setup_bool_define("PLATFORM_BIG_ENDIAN", compiler.platform.big_endian); + setup_bool_define("PLATFORM_I128_SUPPORTED", compiler.platform.int128); + setup_bool_define("PLATFORM_F128_SUPPORTED", compiler.platform.float128); + setup_bool_define("PLATFORM_F16_SUPPORTED", compiler.platform.float16); + setup_int_define("ARCH_TYPE", (uint64_t)compiler.platform.arch, type_int); + setup_int_define("MEMORY_ENVIRONMENT", (uint64_t)compiler.build.memory_environment, type_int); setup_bool_define("COMPILER_LIBC_AVAILABLE", link_libc()); - setup_int_define("COMPILER_OPT_LEVEL", (uint64_t)active_target.optlevel, type_int); - setup_int_define("OS_TYPE", (uint64_t)platform_target.os, type_int); - setup_int_define("COMPILER_SIZE_OPT_LEVEL", (uint64_t)active_target.optsize, type_int); + setup_int_define("COMPILER_OPT_LEVEL", (uint64_t)compiler.build.optlevel, type_int); + setup_int_define("OS_TYPE", (uint64_t)compiler.platform.os, type_int); + setup_int_define("COMPILER_SIZE_OPT_LEVEL", (uint64_t)compiler.build.optsize, type_int); setup_bool_define("COMPILER_SAFE_MODE", safe_mode_enabled()); - setup_bool_define("DEBUG_SYMBOLS", active_target.debug_info == DEBUG_INFO_FULL); - setup_bool_define("BACKTRACE", active_target.show_backtrace != SHOW_BACKTRACE_OFF); + setup_bool_define("DEBUG_SYMBOLS", compiler.build.debug_info == DEBUG_INFO_FULL); + setup_bool_define("BACKTRACE", compiler.build.show_backtrace != SHOW_BACKTRACE_OFF); setup_int_define("LLVM_VERSION", llvm_version_major, type_int); - setup_bool_define("BENCHMARKING", active_target.benchmarking); + setup_bool_define("BENCHMARKING", compiler.build.benchmarking); setup_int_define("JMP_BUF_SIZE", jump_buffer_size(), type_int); - setup_bool_define("TESTING", active_target.testing); + setup_bool_define("TESTING", compiler.build.testing); type_init_cint(); compiler_init_time = bench_mark(); - if (!vec_size(active_target.sources) && !active_target.read_stdin) error_exit("No files to compile."); + if (!vec_size(compiler.build.sources) && !compiler.build.read_stdin) error_exit("No files to compile."); - if (active_target.lex_only) + if (compiler.build.lex_only) { compiler_lex(); compiler_parsing_time = bench_mark(); return; } - if (active_target.parse_only) + if (compiler.build.parse_only) { compiler_parse(); compiler_parsing_time = bench_mark(); @@ -1157,40 +1160,40 @@ void compile() void global_context_add_decl(Decl *decl) { - decltable_set(&global_context.symbols, decl); + decltable_set(&compiler.context.symbols, decl); } void global_context_add_generic_decl(Decl *decl) { - decltable_set(&global_context.generic_symbols, decl); + decltable_set(&compiler.context.generic_symbols, decl); } -void global_context_add_link(const char *link) +void linking_add_link(Linking *linking, const char *link) { - FOREACH(const char *, existing_link, global_context.links) + FOREACH(const char *, existing_link, linking->links) { if (str_eq(link, existing_link)) return; } - vec_add(global_context.links, link); + vec_add(linking->links, link); } void global_context_clear_errors(void) { - global_context.in_panic_mode = false; - global_context.errors_found = 0; - global_context.warnings_found = 0; + compiler.context.in_panic_mode = false; + compiler.context.errors_found = 0; + compiler.context.warnings_found = 0; } void global_context_add_type(Type *type) { DEBUG_LOG("Created type %s.", type->name); assert(type_ok(type)); - vec_add(global_context.type, type); + vec_add(compiler.context.type, type); } const char *get_object_extension(void) { - switch (active_target.arch_os_target) + switch (compiler.build.arch_os_target) { case ANY_WINDOWS_ARCH_OS: return ".obj"; @@ -1202,7 +1205,7 @@ const char *get_object_extension(void) Module *global_context_find_module(const char *name) { assert(name); - return htable_get(&global_context.modules, (void *)name); + return htable_get(&compiler.context.modules, (void *)name); } Module *compiler_find_or_create_module(Path *module_name, const char **parameters) @@ -1218,14 +1221,14 @@ Module *compiler_find_or_create_module(Path *module_name, const char **parameter module->parameters = parameters; module->is_generic = vec_size(parameters) > 0; htable_init(&module->symbols, 0x1000); - htable_set(&global_context.modules, (void *)module_name->module, module); + htable_set(&compiler.context.modules, (void *)module_name->module, module); if (parameters) { - vec_add(global_context.generic_module_list, module); + vec_add(compiler.context.generic_module_list, module); } else { - vec_add(global_context.module_list, module); + vec_add(compiler.context.module_list, module); } return module; diff --git a/src/compiler/compiler.h b/src/compiler/compiler.h index e59cd35cc..5e7bc36d3 100644 --- a/src/compiler/compiler.h +++ b/src/compiler/compiler.h @@ -18,11 +18,4 @@ void print_syntax(BuildOptions *options); void vendor_fetch(BuildOptions *options); int find_padding_length(const char** str, const int count); -extern double compiler_init_time; -extern double compiler_parsing_time; -extern double compiler_sema_time; -extern double compiler_ir_gen_time; -extern double compiler_codegen_time; -extern double compiler_link_time; extern const char* c3_suffix_list[3]; -extern char *arch_os_target[ARCH_OS_TARGET_LAST + 1]; \ No newline at end of file diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 884160165..23695d202 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -13,8 +13,6 @@ #include typedef double Real; - -#define MAX_ARRAYINDEX INT32_MAX typedef uint64_t ByteSize; typedef uint32_t TypeSize; typedef int32_t IndexDiff; @@ -24,7 +22,9 @@ typedef uint32_t AlignSize; typedef int32_t ScopeId; typedef uint32_t ArraySize; typedef uint64_t BitSize; +typedef uint16_t FileId; +#define MAX_ARRAYINDEX INT32_MAX #define MAX_FIXUPS 0xFFFFF #define MAX_HASH_SIZE (512 * 1024 * 1024) #define INVALID_SPAN ((SourceSpan){ .row = 0 }) @@ -32,6 +32,7 @@ typedef uint64_t BitSize; #define MAX_STRING_BUFFER 0x10000 #define INITIAL_SYMBOL_MAP 0x10000 #define INITIAL_GENERIC_SYMBOL_MAP 0x1000 +#define MAX_INCLUDE_DIRECTIVES 2048 #define MAX_MACRO_ITERATIONS 0xFFFFFF #define MAX_PARAMS 255 #define MAX_BITSTRUCT 0x1000 @@ -40,26 +41,22 @@ typedef uint64_t BitSize; #define MAX_PRIORITY 0xFFFF #define MAX_TYPE_SIZE UINT32_MAX #define MAX_GLOBAL_DECL_STACK (65536) -#define MAX_ASM_INSTRUCTION_PARAMS 6 -#define CLOBBER_FLAG_ELEMENTS 4 -#define MAX_CLOBBER_FLAGS (64 * CLOBBER_FLAG_ELEMENTS) #define MEMCMP_INLINE_REGS 8 - -extern const char *project_default_keys[][2]; -extern const int project_default_keys_count; -extern const char *project_target_keys[][2]; -extern const int project_target_keys_count; -extern const char *manifest_default_keys[][2]; -extern const int manifest_default_keys_count; -extern const char *manifest_target_keys[][2]; -extern const int manifest_target_keys_count; - -typedef enum BoolErr__ -{ - BOOL_ERR = -1, - BOOL_FALSE = 0, - BOOL_TRUE = 1, -} BoolErr; +#define UINT128_MAX ((Int128) { UINT64_MAX, UINT64_MAX }) +#define INT128_MAX ((Int128) { INT64_MAX, UINT64_MAX }) +#define INT128_MIN ((Int128) { (uint64_t)INT64_MIN, 0 }) +#define STDIN_FILE_ID 0xFFFF +#define ABI_TYPE_EMPTY ((AbiType) { .type = NULL }) +#define RANGE_EXTEND_PREV(x) do { (x)->span = extend_span_with_token((x)->span, c->prev_span); } while (0) +#define PRINT_ERROR_AT(_node, ...) print_error_at((_node)->span, __VA_ARGS__) +#define RETURN_PRINT_ERROR_AT(_val, _node, ...) do { print_error_at((_node)->span, __VA_ARGS__); return _val; } while (0) +#define PRINT_ERROR_HERE(...) print_error_at(c->span, __VA_ARGS__) +#define RETURN_PRINT_ERROR_HERE(...) do { print_error_at(c->span, __VA_ARGS__); return false; } while (0) +#define PRINT_ERROR_LAST(...) print_error_at(c->prev_span, __VA_ARGS__) +#define RETURN_PRINT_ERROR_LAST(...) do { print_error_at(c->prev_span, __VA_ARGS__); return false; } while (0) +#define SEMA_NOTE(_node, ...) sema_error_prev_at((_node)->span, __VA_ARGS__) +#define EXPAND_EXPR_STRING(str_) (str_)->const_expr.bytes.len, (str_)->const_expr.bytes.ptr +#define TABLE_MAX_LOAD 0.5 typedef struct Ast_ Ast; typedef struct Decl_ Decl; @@ -77,7 +74,6 @@ typedef unsigned DeclId; typedef unsigned TypeInfoId; typedef struct SemaContext_ SemaContext; - typedef struct Int128_ { uint64_t high; @@ -96,30 +92,6 @@ typedef struct TypeKind type; } Float; -#define UINT128_MAX ((Int128) { UINT64_MAX, UINT64_MAX }) -#define INT128_MAX ((Int128) { INT64_MAX, UINT64_MAX }) -#define INT128_MIN ((Int128) { (uint64_t)INT64_MIN, 0 }) - -typedef enum -{ - CONST_INIT_ZERO, - CONST_INIT_STRUCT, - CONST_INIT_UNION, - CONST_INIT_VALUE, - CONST_INIT_ARRAY, - CONST_INIT_ARRAY_FULL, - CONST_INIT_ARRAY_VALUE, -} ConstInitType; - -typedef enum -{ - RESOLVE_TYPE_DEFAULT, - RESOLVE_TYPE_ALLOW_INFER = 0x01, - RESOLVE_TYPE_ALLOW_FLEXIBLE = 0x02, - RESOLVE_TYPE_MACRO_METHOD = RESOLVE_TYPE_ALLOW_INFER, - RESOLVE_TYPE_FUNC_METHOD = RESOLVE_TYPE_DEFAULT -} ResolveTypeKind; - struct ConstInitializer_ { ConstInitType kind; @@ -147,60 +119,6 @@ struct ConstInitializer_ }; }; -typedef struct -{ - char string[1024]; - unsigned constraint_len; -} ClobberList; - - -typedef struct -{ - bool is_write : 1; - bool is_readwrite : 1; - bool is_address : 1; - AsmArgBits imm_arg_ubits : 16; - AsmArgBits imm_arg_ibits : 16; - AsmArgBits ireg_bits : 16; - AsmArgBits float_bits : 16; - AsmArgBits vec_bits : 16; -} AsmArgType; - -typedef struct -{ - const char *name; - AsmRegisterType type; - AsmArgBits bits; - int clobber_index; -} AsmRegister; - -typedef struct -{ - uint64_t mask[CLOBBER_FLAG_ELEMENTS]; -} Clobbers; - -typedef struct -{ - const char *name; - AsmArgType param[MAX_ASM_INSTRUCTION_PARAMS]; - unsigned param_count; - Clobbers mask; -} AsmInstruction; - -#define ASM_INSTRUCTION_MAX 0x1000 -#define ASM_INSTRUCTION_MASK (ASM_INSTRUCTION_MAX - 1) -#define ASM_REGISTER_MAX 4096 -#define ASM_REGISTER_MASK (ASM_REGISTER_MAX - 1) - -typedef struct -{ - bool initialized; - const char **clobber_name_list; - const char *extra_clobbers; - AsmRegister registers[ASM_REGISTER_MAX]; - AsmInstruction instructions[ASM_INSTRUCTION_MAX]; - unsigned register_count; -} AsmTarget; typedef struct { @@ -232,8 +150,6 @@ typedef struct } ExprConst; -typedef uint16_t FileId; - typedef struct { FileId file_id; @@ -256,8 +172,6 @@ typedef union uint64_t a; } SourceSpan; -extern File stdin_file; -#define stdin_file_id 0xFFFF static_assert(sizeof(SourceSpan) == 8, "Expected 8 bytes"); @@ -366,16 +280,6 @@ struct Type_ }; }; -typedef enum -{ - TYPE_COMPRESSED_NONE = 0, - TYPE_COMPRESSED_PTR = 1, - TYPE_COMPRESSED_SUB = 2, - TYPE_COMPRESSED_SUBPTR = 3, - TYPE_COMPRESSED_PTRPTR = 4, - TYPE_COMPRESSED_PTRSUB = 5, - TYPE_COMPRESSED_SUBSUB = 6, -} TypeInfoCompressedKind; struct TypeInfo_ { @@ -544,16 +448,6 @@ typedef struct TypeInfo *type_info; } EnumDecl; -typedef enum -{ - VARIADIC_NONE, - VARIADIC_TYPED, - VARIADIC_ANY, - VARIADIC_RAW, -} Variadic; - - - struct Signature_ { CalleeAttributes attrs; @@ -567,8 +461,6 @@ struct Signature_ Decl** params; }; - - typedef struct { TypeInfoId type_parent; @@ -627,12 +519,6 @@ typedef struct }; } TypedefDecl; -typedef enum -{ - DEFINE_IDENT_ALIAS, - DEFINE_IDENT_GENERIC, -} DefineType; - typedef struct { DefineType define_kind: 5; @@ -759,8 +645,7 @@ typedef struct Decl_ }; } Decl; -// static_assert(sizeof(void*) != 8 || sizeof(Decl) == 136, "Decl has unexpected size."); - +static_assert(sizeof(void*) != 8 || sizeof(Decl) == 136, "Decl has unexpected size."); typedef struct { @@ -858,17 +743,6 @@ typedef struct ExprId offset; } ExprPointerOffset; -typedef enum -{ - ACCESS_LEN, - ACCESS_PTR, - ACCESS_TYPEOFANY, - ACCESS_TYPEOFANYFAULT, - ACCESS_ENUMNAME, - ACCESS_FAULTNAME, - ACCESS_FAULTORDINAL, -} BuiltinAccessKind; - typedef struct { BuiltinAccessKind kind : 8; @@ -880,6 +754,7 @@ typedef struct Expr *filename; Expr *len; } ExprEmbedExpr; + typedef struct { ExprId parent; @@ -923,6 +798,7 @@ typedef struct Decl *type; TypeProperty property; } ExprTagOf; + typedef struct { union @@ -955,8 +831,6 @@ typedef struct Decl *decl; } ExprIdentifierRaw; - - typedef struct { TokenType token_type; @@ -975,19 +849,6 @@ typedef struct }; } ExprCtCall; - -typedef enum -{ - ASM_SCALE_1, - ASM_SCALE_2, - ASM_SCALE_4, - ASM_SCALE_8, - ASM_SCALE_SHR, - ASM_SCALE_SHL, - ASM_SCALE_ASHL, - ASM_SCALE_ROR, - ASM_SCALE_RRX, -} AsmOffsetType; typedef struct { AsmArgKind kind : 8; @@ -1077,8 +938,6 @@ typedef struct BlockExit **block_exit; } ExprMacroBlock; - - typedef struct { Expr *initializer; @@ -1251,9 +1110,8 @@ struct Expr_ Range vasplat_expr; }; }; -//static_assert(sizeof(ExprConst) == 32, "Not expected size"); -static_assert(sizeof(Expr) == 56, "Expr not expected size"); +static_assert(sizeof(void*) != 8 || sizeof(Expr) == 56, "Expr not expected size"); typedef struct { @@ -1261,7 +1119,6 @@ typedef struct AstId parent_defer; } AstCompoundStmt; - typedef struct { Expr *expr; // May be NULL @@ -1280,8 +1137,6 @@ typedef struct bool jump : 1; } FlowCommon; - - typedef struct { FlowCommon flow; @@ -1389,8 +1244,6 @@ typedef struct bool is_catch : 1; } AstDeferStmt; - - typedef struct AstCtIfStmt_ { Expr *expr; @@ -1562,8 +1415,7 @@ typedef struct Ast_ } Ast; -//static_assert(sizeof(AstContinueBreakStmt) == 24, "Ooops"); -static_assert(sizeof(Ast) == 56, "Not expected size on 64 bit"); +static_assert(sizeof(void*) != 8 || sizeof(Ast) == 56, "Not expected Ast size"); typedef struct Module_ { @@ -1715,14 +1567,6 @@ typedef struct ParseContext_ Lexer lexer; } ParseContext; -typedef enum -{ - CALL_ENV_GLOBAL_INIT, - CALL_ENV_FUNCTION, - CALL_ENV_FUNCTION_STATIC, - CALL_ENV_ATTR, -} CallEnvKind; - typedef struct { CallEnvKind kind : 8; @@ -1785,58 +1629,6 @@ struct SemaContext_ Expr *return_expr; }; - -typedef struct -{ - HTable modules; - Module *core_module; - CompilationUnit *core_unit; - Module **module_list; - Module **generic_module_list; - Type **type; - Decl** method_extensions; - const char *lib_dir; - const char **sources; - File **loaded_sources; - bool in_panic_mode : 1; - unsigned errors_found; - unsigned warnings_found; - unsigned includes_used; - Decl ***locals_list; - const char **links; - bool silence_deprecation; - HTable compiler_defines; - HTable features; - Module std_module; - DeclTable symbols; - DeclTable generic_symbols; - Path std_module_path; - Type *string_type; - Decl *panic_var; - Decl *panicf; - Decl *io_error_file_not_found; - Decl *main; - Decl *test_func; - Decl *benchmark_func; - Decl *decl_stack[MAX_GLOBAL_DECL_STACK]; - Decl **decl_stack_bottom; - Decl **decl_stack_top; -} GlobalContext; - - -typedef enum -{ - ABI_ARG_IGNORE, - ABI_ARG_DIRECT, - ABI_ARG_DIRECT_PAIR, - ABI_ARG_DIRECT_COERCE, - ABI_ARG_DIRECT_COERCE_INT, - ABI_ARG_DIRECT_SPLIT_STRUCT_I32, - ABI_ARG_EXPAND_COERCE, - ABI_ARG_INDIRECT, - ABI_ARG_EXPAND, -} ABIKind; - typedef struct { union @@ -1846,8 +1638,6 @@ typedef struct }; } AbiType; -#define ABI_TYPE_EMPTY ((AbiType) { .type = NULL }) - typedef struct ABIArgInfo_ { ArrayIndex param_index_start : 16; @@ -1937,17 +1727,62 @@ typedef struct CopyStruct_ bool is_template; } CopyStruct; +typedef struct +{ + const char **links; +} Linking; -extern GlobalContext global_context; -extern AsmTarget asm_target; -extern BuildTarget active_target; +typedef struct +{ + HTable modules; + Module *core_module; + CompilationUnit *core_unit; + Module **module_list; + Module **generic_module_list; + Type **type; + Decl** method_extensions; + const char *lib_dir; + const char **sources; + File **loaded_sources; + bool in_panic_mode : 1; + unsigned errors_found; + unsigned warnings_found; + unsigned includes_used; + Decl ***locals_list; + bool silence_deprecation; + HTable compiler_defines; + HTable features; + Module std_module; + DeclTable symbols; + DeclTable generic_symbols; + Path std_module_path; + Type *string_type; + Decl *panic_var; + Decl *panicf; + Decl *io_error_file_not_found; + Decl *main; + Decl *test_func; + Decl *benchmark_func; + Decl *decl_stack[MAX_GLOBAL_DECL_STACK]; + Decl **decl_stack_bottom; + Decl **decl_stack_top; +} GlobalContext; + +typedef struct +{ + BuildTarget build; + PlatformTarget platform; + Linking linking; + GlobalContext context; +} CompilerState; + +extern CompilerState compiler; extern Ast *poisoned_ast; extern Decl *poisoned_decl; extern Expr *poisoned_expr; extern Type *poisoned_type; extern TypeInfo *poisoned_type_info; - extern Type *type_bool, *type_void, *type_voidptr; extern Type *type_float16, *type_bfloat, *type_float, *type_double, *type_f128; extern Type *type_ichar, *type_short, *type_int, *type_long, *type_isz; @@ -1962,7 +1797,7 @@ extern Type *type_cuint; extern Type *type_chars; extern Type *type_wildcard_optional; extern Type *type_string; - +extern File stdin_file; extern const char *attribute_list[NUMBER_OF_ATTRIBUTES]; extern const char *builtin_list[NUMBER_OF_BUILTINS]; @@ -2020,27 +1855,27 @@ INLINE Type *typeget(TypeInfoId id_) INLINE bool no_panic(void) { - return active_target.feature.panic_level == PANIC_OFF; + return compiler.build.feature.panic_level == PANIC_OFF; } INLINE bool safe_mode_enabled(void) { - return active_target.feature.safe_mode != SAFETY_OFF; + return compiler.build.feature.safe_mode != SAFETY_OFF; } INLINE bool link_libc(void) { - return active_target.link_libc != LINK_LIBC_OFF; + return compiler.build.link_libc != LINK_LIBC_OFF; } INLINE bool strip_unused(void) { - return active_target.strip_unused != STRIP_UNUSED_OFF; + return compiler.build.strip_unused != STRIP_UNUSED_OFF; } INLINE bool no_stdlib(void) { - return active_target.use_stdlib == USE_STDLIB_OFF; + return compiler.build.use_stdlib == USE_STDLIB_OFF; } bool ast_is_not_empty(Ast *ast); @@ -2064,14 +1899,6 @@ static inline SourceSpan extend_span_with_token(SourceSpan loc, SourceSpan after return loc; } - -typedef enum CmpRes_ -{ - CMP_LT = -1, - CMP_EQ = 0, - CMP_GT = 1, -} CmpRes; - AttributeType attribute_by_name(const char *name); void type_setup(PlatformTarget *target); @@ -2188,9 +2015,9 @@ Ast *copy_ast_macro(Ast *source_ast); Ast *copy_ast_defer(Ast *source_ast); TypeInfo *copy_type_info_single(TypeInfo *type_info); -void init_asm(void); -AsmRegister *asm_reg_by_name(const char *name); -AsmInstruction *asm_instr_by_name(const char *name); +void init_asm(PlatformTarget *target); +AsmRegister *asm_reg_by_name(PlatformTarget *target, const char *name); +AsmInstruction *asm_instr_by_name(PlatformTarget *target, const char *name); INLINE const char *asm_clobber_by_index(unsigned index); INLINE AsmRegister *asm_reg_by_index(unsigned index); @@ -2223,7 +2050,7 @@ void global_context_add_type(Type *type); void global_context_add_decl(Decl *type_decl); void global_context_add_generic_decl(Decl *decl); -void global_context_add_link(const char *link); +void linking_add_link(Linking *linker, const char *link); Module *compiler_find_or_create_module(Path *module_name, const char **parameters); Module *global_context_find_module(const char *name); @@ -2349,15 +2176,6 @@ Ast *parse_include_file_stmts(File *file, CompilationUnit *unit); bool parse_stdin(void); Path *path_create_from_string(const char *string, uint32_t len, SourceSpan span); -#define PRINT_ERROR_AT(_node, ...) print_error_at((_node)->span, __VA_ARGS__) -#define RETURN_PRINT_ERROR_AT(_val, _node, ...) do { print_error_at((_node)->span, __VA_ARGS__); return _val; } while (0) -#define PRINT_ERROR_HERE(...) print_error_at(c->span, __VA_ARGS__) -#define RETURN_PRINT_ERROR_HERE(...) do { print_error_at(c->span, __VA_ARGS__); return false; } while (0) -#define PRINT_ERROR_LAST(...) print_error_at(c->prev_span, __VA_ARGS__) -#define RETURN_PRINT_ERROR_LAST(...) do { print_error_at(c->prev_span, __VA_ARGS__); return false; } while (0) -#define SEMA_NOTE(_node, ...) sema_error_prev_at((_node)->span, __VA_ARGS__) -#define EXPAND_EXPR_STRING(str_) (str_)->const_expr.bytes.len, (str_)->const_expr.bytes.ptr -#define TABLE_MAX_LOAD 0.5 void sema_analysis_run(void); Decl **sema_decl_stack_store(void); @@ -2437,8 +2255,6 @@ File *compile_and_invoke(const char *file, const char *args); void compiler_parse(void); void emit_json(void); -#define RANGE_EXTEND_PREV(x) do { (x)->span = extend_span_with_token((x)->span, c->prev_span); } while (0) - void stable_init(STable *table, uint32_t initial_size); void *stable_set(STable *table, const char *key, void *value); void *stable_get(STable *table, const char *key); @@ -2529,15 +2345,6 @@ bool type_may_have_sub_elements(Type *type); bool type_may_have_method(Type *type); void type_append_name_to_scratch(Type *type); -typedef enum -{ - TYPE_MISMATCH = 0, - TYPE_SAME = 1, - TYPE_SAME_INT_SIZE = 2, - TYPE_ALIGNMENT_INCREASE = 3, - TYPE_ERROR = -1, -} TypeCmpResult; - TypeCmpResult type_is_pointer_equivalent(SemaContext *context, Type *to_pointer, Type *from_pointer, bool flatten_distinct); TypeCmpResult type_array_element_is_equivalent(SemaContext *context, Type *element1, Type *element2, bool is_explicit); FunctionPrototype *type_get_resolved_prototype(Type *type); @@ -2915,15 +2722,6 @@ INLINE const char *type_invalid_storage_type_name(Type *type) } } -typedef enum -{ - STORAGE_NORMAL, - STORAGE_VOID, - STORAGE_COMPILE_TIME, - STORAGE_WILDCARD, - STORAGE_UNKNOWN -} StorageType; - static inline StorageType type_storage_type(Type *type) { if (!type) return STORAGE_NORMAL; @@ -3514,7 +3312,7 @@ INLINE Expr *expr_new_expr(ExprKind kind, Expr *expr) INLINE bool type_is_promotable_int_bool(Type *type) { // If we support other architectures, update this. - return type_is_integer_or_bool_kind(type) && type->builtin.bitsize < platform_target.width_c_int; + return type_is_integer_or_bool_kind(type) && type->builtin.bitsize < compiler.platform.width_c_int; } INLINE bool type_is_promotable_float(Type *type) @@ -3553,6 +3351,7 @@ bool linker(const char *output_file, const char **files, unsigned file_count); void platform_linker(const char *output_file, const char **files, unsigned file_count); const char *cc_compiler(const char *cc, const char *file, const char *flags, const char **include_dirs, const char *output_subdir); const char *arch_to_linker_arch(ArchType arch); +extern char swizzle[256]; #define CAT(a,b) CAT2(a,b) // force expand #define CAT2(a,b) a##b // actually concatenate @@ -3719,12 +3518,12 @@ INLINE void expr_rewrite_const_float(Expr *expr, Type *type, Real d) INLINE const char *asm_clobber_by_index(unsigned index) { - return asm_target.clobber_name_list[index]; + return compiler.platform.clobber_name_list[index]; } INLINE AsmRegister *asm_reg_by_index(unsigned index) { - return &asm_target.registers[index]; + return &compiler.platform.registers[index]; } INLINE void clobbers_add(Clobbers *clobbers, unsigned index) @@ -3871,4 +3670,3 @@ INLINE bool check_module_name(Path *path) return true; } -extern char swizzle[256]; diff --git a/src/compiler/diagnostics.c b/src/compiler/diagnostics.c index f6aac6796..b2c9602ce 100644 --- a/src/compiler/diagnostics.c +++ b/src/compiler/diagnostics.c @@ -7,12 +7,6 @@ -typedef enum -{ - PRINT_TYPE_ERROR, - PRINT_TYPE_NOTE, - PRINT_TYPE_WARN -} PrintType; #define LINES_SHOWN 4 #define MAX_WIDTH 120 @@ -25,7 +19,7 @@ static void print_error_type_at(SourceSpan location, const char *message, PrintT return; } File *file = source_file_by_id(location.file_id); - if (active_target.test_output || active_target.benchmark_output) + if (compiler.build.test_output || compiler.build.benchmark_output) { switch (print_type) { @@ -161,7 +155,7 @@ static void vprint_error(SourceSpan location, const char *message, va_list args) void sema_verror_range(SourceSpan location, const char *message, va_list args) { vprint_error(location, message, args); - global_context.errors_found++; + compiler.context.errors_found++; } void sema_warning_at(SourceSpan loc, const char *message, ...) @@ -210,7 +204,7 @@ void sema_error_prev_at(SourceSpan loc, const char *message, ...) void print_error(ParseContext *context, const char *message, ...) { - global_context.errors_found++; + compiler.context.errors_found++; File *file = context->unit->file; va_list list; va_start(list, message); diff --git a/src/compiler/enums.h b/src/compiler/enums.h index a9a1ad45a..4dac2d558 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -13,10 +13,287 @@ typedef enum { - COND_MISSING = -1, - COND_TRUE = 1, - COND_FALSE = 0, -} CondResult; + ABI_UNKNOWN, + ABI_X64, + ABI_WIN64, + ABI_X86, + ABI_AARCH64, + ABI_WASM, + ABI_ARM, + ABI_PPC32, + ABI_PPC64_SVR4, + ABI_RISCV, + ABI_XTENSA, +} ABI; + +typedef enum +{ + ABI_ARG_IGNORE, + ABI_ARG_DIRECT, + ABI_ARG_DIRECT_PAIR, + ABI_ARG_DIRECT_COERCE, + ABI_ARG_DIRECT_COERCE_INT, + ABI_ARG_DIRECT_SPLIT_STRUCT_I32, + ABI_ARG_EXPAND_COERCE, + ABI_ARG_INDIRECT, + ABI_ARG_EXPAND, +} ABIKind; + +typedef enum +{ + ANALYSIS_NOT_BEGUN, + ANALYSIS_MODULE_HIERARCHY, + ANALYSIS_MODULE_TOP, + ANALYSIS_IMPORTS, + ANALYSIS_REGISTER_GLOBAL_DECLARATIONS, + ANALYSIS_REGISTER_CONDITIONAL_UNITS, + ANALYSIS_REGISTER_CONDITIONAL_DECLARATIONS, + ANALYSIS_DECLS, + ANALYSIS_CT_ECHO, + ANALYSIS_CT_ASSERT, + ANALYSIS_FUNCTIONS, + ANALYSIS_INTERFACE, + ANALYSIS_FINALIZE, + ANALYSIS_LAST = ANALYSIS_FINALIZE +} AnalysisStage; + +// Note: This list is derived from Clang, only a subset is used by C3. +typedef enum +{ + ARCH_TYPE_UNKNOWN, + ARCH_TYPE_ARM, // ARM (little endian): arm, armv.*, xscale + ARCH_TYPE_ARMB, // ARM (big endian): armeb + ARCH_TYPE_AARCH64, // AArch64 (little endian): aarch64 + ARCH_TYPE_AARCH64_BE, // AArch64 (big endian): aarch64_be + ARCH_TYPE_AARCH64_32, // AArch64 (little endian) ILP32: aarch64_32 + ARCH_TYPE_ARC, // ARC: Synopsys ARC + ARCH_TYPE_AVR, // AVR: Atmel AVR microcontroller + ARCH_TYPE_BPFEL, // eBPF or extended BPF or 64-bit BPF (little endian) + ARCH_TYPE_BPFEB, // eBPF or extended BPF or 64-bit BPF (big endian) + ARCH_TYPE_HEXAGON, // Hexagon: hexagon + ARCH_TYPE_MIPS, // MIPS: mips, mipsallegrex, mipsr6 + ARCH_TYPE_MIPSEL, // MIPSEL: mipsel, mipsallegrexe, mipsr6el + ARCH_TYPE_MIPS64, // MIPS64: mips64, mips64r6, mipsn32, mipsn32r6 + ARCH_TYPE_MIPS64EL, // MIPS64EL: mips64el, mips64r6el, mipsn32el, mipsn32r6el + ARCH_TYPE_MSP430, // MSP430: msp430 + ARCH_TYPE_PPC, // PPC: powerpc + ARCH_TYPE_PPC64, // PPC64: powerpc64, ppu + ARCH_TYPE_PPC64LE, // PPC64LE: powerpc64le + ARCH_TYPE_R600, // R600: AMD GPUs HD2XXX - HD6XXX + ARCH_TYPE_AMDGCN, // AMDGCN: AMD GCN GPUs + ARCH_TYPE_RISCV32, // RISC-V (32-bit): riscv32 + ARCH_TYPE_RISCV64, // RISC-V (64-bit): riscv64 + ARCH_TYPE_SPARC, // Sparc: sparc + ARCH_TYPE_SPARCV9, // Sparcv9: Sparcv9 + ARCH_TYPE_SPARCEL, // Sparc: (endianness = little). NB: 'Sparcle' is a CPU variant + ARCH_TYPE_SYSTEMZ, // SystemZ: s390x + ARCH_TYPE_TCE, // TCE (http://tce.cs.tut.fi/): tce + ARCH_TYPE_TCELE, // TCE little endian (http://tce.cs.tut.fi/): tcele + ARCH_TYPE_THUMB, // Thumb (little endian): thumb, thumbv.* + ARCH_TYPE_THUMBEB, // Thumb (big endian): thumbeb + ARCH_TYPE_X86, // X86: i[3-9]86 + ARCH_TYPE_X86_64, // X86-64: amd64, x86_64 + ARCH_TYPE_XCORE, // XCore: xcore + ARCH_TYPE_NVPTX, // NVPTX: 32-bit + ARCH_TYPE_NVPTX64, // NVPTX: 64-bit + ARCH_TYPE_LE32, // le32: generic little-endian 32-bit CPU (PNaCl) + ARCH_TYPE_LE64, // le64: generic little-endian 64-bit CPU (PNaCl) + ARCH_TYPE_AMDIL, // AMDIL + ARCH_TYPE_AMDIL64, // AMDIL with 64-bit pointers + ARCH_TYPE_HSAIL, // AMD HSAIL + ARCH_TYPE_HSAIL64, // AMD HSAIL with 64-bit pointers + ARCH_TYPE_SPIR, // SPIR: standard portable IR for OpenCL 32-bit version + ARCH_TYPE_SPIR64, // SPIR: standard portable IR for OpenCL 64-bit version + ARCH_TYPE_KALIMBA, // Kalimba: generic kalimba + ARCH_TYPE_SHAVE, // SHAVE: Movidius vector VLIW processors + ARCH_TYPE_LANAI, // Lanai: Lanai 32-bit + ARCH_TYPE_WASM32, // WebAssembly with 32-bit pointers + ARCH_TYPE_WASM64, // WebAssembly with 64-bit pointers + ARCH_TYPE_RSCRIPT32, // 32-bit RenderScript + ARCH_TYPE_RSCRIPT64, // 64-bit RenderScript + ARCH_TYPE_XTENSA, // Xtensa + ARCH_TYPE_LAST = ARCH_TYPE_XTENSA +} ArchType; + +typedef enum +{ + ARM_AAPCS, + ARM_AAPCS16, + ARM_APCS_GNU, + ARM_AAPCS_LINUX, +} ARMVariant; + +typedef enum +{ + ARM_ABI_AAPCS, + ARM_ABI_APCS, + ARM_ABI_AAPCS16_VFP, + ARM_ABI_AAPCS_VFP, +} ARMABIVariant; + +typedef enum FLAG_ATTR +{ + ARG_BITS_8 = 1 << 0, + ARG_BITS_16 = 1 << 1, + ARG_BITS_32 = 1 << 2, + ARG_BITS_64 = 1 << 3, + ARG_BITS_128 = 1 << 4, + ARG_BITS_256 = 1 << 5, + ARG_BITS_512 = 1 << 6, + ARG_BITS_80 = 1 << 7, +} AsmArgBits; + +typedef enum +{ + ASM_ARG_REG, + ASM_ARG_ADDR, + ASM_ARG_REGVAR, + ASM_ARG_ADDROF, + ASM_ARG_MEMVAR, + ASM_ARG_VALUE, + ASM_ARG_INT, +} AsmArgKind; + +typedef enum +{ + ASM_SCALE_1, + ASM_SCALE_2, + ASM_SCALE_4, + ASM_SCALE_8, + ASM_SCALE_SHR, + ASM_SCALE_SHL, + ASM_SCALE_ASHL, + ASM_SCALE_ROR, + ASM_SCALE_RRX, +} AsmOffsetType; + +typedef enum +{ + ASM_REG_INT, + ASM_REG_FLOAT, + ASM_REG_IVEC, + ASM_REF_FVEC, +} AsmRegisterType; + +typedef enum +{ + AST_POISONED, + AST_ASM_STMT, + AST_ASM_BLOCK_STMT, + AST_ASSERT_STMT, + AST_BREAK_STMT, + AST_CASE_STMT, + AST_COMPOUND_STMT, + AST_CONTINUE_STMT, + AST_CT_ASSERT, + AST_CT_ECHO_STMT, + AST_CT_ELSE_STMT, + AST_CT_FOREACH_STMT, + AST_CT_FOR_STMT, + AST_CT_IF_STMT, + AST_CT_SWITCH_STMT, + AST_DECLARE_STMT, + AST_DECLS_STMT, + AST_DEFAULT_STMT, + AST_DEFER_STMT, + AST_EXPR_STMT, + AST_FOR_STMT, + AST_FOREACH_STMT, + AST_IF_CATCH_SWITCH_STMT, + AST_IF_STMT, + AST_NOP_STMT, + AST_RETURN_STMT, + AST_BLOCK_EXIT_STMT, + AST_SWITCH_STMT, + AST_NEXTCASE_STMT, + AST_CONTRACT, + AST_CONTRACT_FAULT, +} AstKind; + +typedef enum +{ + ATOMIC_NONE, + ATOMIC_UNORDERED, + ATOMIC_RELAXED, + ATOMIC_ACQUIRE, + ATOMIC_RELEASE, + ATOMIC_ACQUIRE_RELEASE, + ATOMIC_SEQ_CONSISTENT, +} Atomicity; + +typedef enum FLAG_ATTR +{ + ATTR_FUNC = 1 << 0, + ATTR_GLOBAL = 1 << 1, + ATTR_LOCAL = 1 << 2, + ATTR_ENUM = 1 << 3, + ATTR_STRUCT = 1 << 4, + ATTR_UNION = 1 << 5, + ATTR_CONST = 1 << 6, + ATTR_FAULT = 1 << 7, + ATTR_DEF = 1 << 8, + ATTR_MEMBER = 1 << 9, + ATTR_BITSTRUCT_MEMBER = 1 << 10, + ATTR_INTERFACE = 1 << 11, + ATTR_CALL = 1 << 12, + ATTR_BITSTRUCT = 1 << 13, + ATTR_MACRO = 1 << 14, + ATTR_DISTINCT = 1 << 15, + ATTR_ENUM_VALUE = 1 << 16, + ATTR_INTERFACE_METHOD = 1 << 17, + ATTR_PARAM = 1 << 18, +} AttributeDomain; + +typedef enum +{ + ATTRIBUTE_ALIGN, + ATTRIBUTE_BENCHMARK, + ATTRIBUTE_BIGENDIAN, + ATTRIBUTE_BUILTIN, + ATTRIBUTE_CALLCONV, + ATTRIBUTE_COMPACT, + ATTRIBUTE_CONST, + ATTRIBUTE_DEPRECATED, + ATTRIBUTE_DYNAMIC, + ATTRIBUTE_EXPORT, + ATTRIBUTE_EXTERN, + ATTRIBUTE_FINALIZER, + ATTRIBUTE_IF, + ATTRIBUTE_INLINE, + ATTRIBUTE_INIT, + ATTRIBUTE_LINK, + ATTRIBUTE_LITTLEENDIAN, + ATTRIBUTE_LOCAL, + ATTRIBUTE_MAYDISCARD, + ATTRIBUTE_NAKED, + ATTRIBUTE_NOALIAS, + ATTRIBUTE_NODISCARD, + ATTRIBUTE_NOINIT, + ATTRIBUTE_NOINLINE, + ATTRIBUTE_NOPADDING, + ATTRIBUTE_NORETURN, + ATTRIBUTE_NOSTRIP, + ATTRIBUTE_OBFUSCATE, + ATTRIBUTE_OPERATOR, + ATTRIBUTE_OPTIONAL, + ATTRIBUTE_OVERLAP, + ATTRIBUTE_PACKED, + ATTRIBUTE_PRIVATE, + ATTRIBUTE_PUBLIC, + ATTRIBUTE_PURE, + ATTRIBUTE_REFLECT, + ATTRIBUTE_SAFEMACRO, + ATTRIBUTE_SECTION, + ATTRIBUTE_TAG, + ATTRIBUTE_TEST, + ATTRIBUTE_UNUSED, + ATTRIBUTE_USED, + ATTRIBUTE_WASM, + ATTRIBUTE_WEAK, + ATTRIBUTE_WINMAIN, + ATTRIBUTE_NONE, + NUMBER_OF_ATTRIBUTES = ATTRIBUTE_NONE, +} AttributeType; typedef enum { @@ -61,43 +338,187 @@ typedef enum typedef enum { - AST_POISONED, - AST_ASM_STMT, - AST_ASM_BLOCK_STMT, - AST_ASSERT_STMT, - AST_BREAK_STMT, - AST_CASE_STMT, - AST_COMPOUND_STMT, - AST_CONTINUE_STMT, - AST_CT_ASSERT, - AST_CT_ECHO_STMT, - AST_CT_ELSE_STMT, - AST_CT_FOREACH_STMT, - AST_CT_FOR_STMT, - AST_CT_IF_STMT, - AST_CT_SWITCH_STMT, - AST_DECLARE_STMT, - AST_DECLS_STMT, - AST_DEFAULT_STMT, - AST_DEFER_STMT, - AST_EXPR_STMT, - AST_FOR_STMT, - AST_FOREACH_STMT, - AST_IF_CATCH_SWITCH_STMT, - AST_IF_STMT, - AST_NOP_STMT, - AST_RETURN_STMT, - AST_BLOCK_EXIT_STMT, - AST_SWITCH_STMT, - AST_NEXTCASE_STMT, - AST_CONTRACT, - AST_CONTRACT_FAULT, -} AstKind; + BIT1, + BITS8, + BITS16, + BITS32, + BITS64, + BITS128, + BITS256, + BITSIZES_LEN +} BitSizes; -#define CT_AST \ - AST_CT_ASSERT: case AST_CT_ECHO_STMT: case AST_CT_ELSE_STMT: \ - case AST_CT_FOREACH_STMT: case AST_CT_FOR_STMT: \ - case AST_CT_IF_STMT: case AST_CT_SWITCH_STMT +typedef enum BoolErr__ +{ + BOOL_ERR = -1, + BOOL_FALSE = 0, + BOOL_TRUE = 1, +} BoolErr; + +typedef enum +{ + ACCESS_LEN, + ACCESS_PTR, + ACCESS_TYPEOFANY, + ACCESS_TYPEOFANYFAULT, + ACCESS_ENUMNAME, + ACCESS_FAULTNAME, + ACCESS_FAULTORDINAL, +} BuiltinAccessKind; + +typedef enum +{ + BUILTIN_DEF_DATE, + BUILTIN_DEF_FILE, + BUILTIN_DEF_FILEPATH, + BUILTIN_DEF_FUNC, + BUILTIN_DEF_FUNCTION, + BUILTIN_DEF_LINE, + BUILTIN_DEF_LINE_RAW, + BUILTIN_DEF_MODULE, + BUILTIN_DEF_BENCHMARK_NAMES, + BUILTIN_DEF_BENCHMARK_FNS, + BUILTIN_DEF_TEST_NAMES, + BUILTIN_DEF_TEST_FNS, + BUILTIN_DEF_TIME, + BUILTIN_DEF_NONE, + NUMBER_OF_BUILTIN_DEFINES = BUILTIN_DEF_NONE +} BuiltinDefine; + +typedef enum +{ + BUILTIN_ABS, + BUILTIN_ANY_MAKE, + BUILTIN_ATOMIC_LOAD, + BUILTIN_ATOMIC_STORE, + BUILTIN_ATOMIC_FETCH_EXCHANGE, + BUILTIN_ATOMIC_FETCH_ADD, + BUILTIN_ATOMIC_FETCH_SUB, + BUILTIN_ATOMIC_FETCH_AND, + BUILTIN_ATOMIC_FETCH_NAND, + BUILTIN_ATOMIC_FETCH_OR, + BUILTIN_ATOMIC_FETCH_XOR, + BUILTIN_ATOMIC_FETCH_MAX, + BUILTIN_ATOMIC_FETCH_MIN, + BUILTIN_ATOMIC_FETCH_INC_WRAP, + BUILTIN_ATOMIC_FETCH_DEC_WRAP, + BUILTIN_BITREVERSE, + BUILTIN_BREAKPOINT, + BUILTIN_BSWAP, + BUILTIN_CEIL, + BUILTIN_COMPARE_EXCHANGE, + BUILTIN_COPYSIGN, + BUILTIN_COS, + BUILTIN_CTLZ, + BUILTIN_CTTZ, + BUILTIN_EXACT_ADD, + BUILTIN_EXACT_DIV, + BUILTIN_EXACT_MOD, + BUILTIN_EXACT_MUL, + BUILTIN_EXACT_NEG, + BUILTIN_EXACT_SUB, + BUILTIN_EXP, + BUILTIN_EXP2, + BUILTIN_EXPECT, + BUILTIN_EXPECT_WITH_PROBABILITY, + BUILTIN_FLOOR, + BUILTIN_FMA, + BUILTIN_FMULADD, + BUILTIN_FRAMEADDRESS, + BUILTIN_FSHL, + BUILTIN_FSHR, + BUILTIN_GATHER, + BUILTIN_GET_ROUNDING_MODE, + BUILTIN_LOG, + BUILTIN_LOG10, + BUILTIN_LOG2, + BUILTIN_MASKED_LOAD, + BUILTIN_MASKED_STORE, + BUILTIN_MAX, + BUILTIN_MEMCOPY, + BUILTIN_MEMCOPY_INLINE, + BUILTIN_MEMMOVE, + BUILTIN_MEMSET, + BUILTIN_MEMSET_INLINE, + BUILTIN_MIN, + BUILTIN_NEARBYINT, + BUILTIN_OVERFLOW_ADD, + BUILTIN_OVERFLOW_MUL, + BUILTIN_OVERFLOW_SUB, + BUILTIN_POPCOUNT, + BUILTIN_POW, + BUILTIN_POW_INT, + BUILTIN_PREFETCH, + BUILTIN_REDUCE_ADD, + BUILTIN_REDUCE_AND, + BUILTIN_REDUCE_FADD, + BUILTIN_REDUCE_FMUL, + BUILTIN_REDUCE_MAX, + BUILTIN_REDUCE_MIN, + BUILTIN_REDUCE_MUL, + BUILTIN_REDUCE_OR, + BUILTIN_REDUCE_XOR, + BUILTIN_REVERSE, + BUILTIN_RETURNADDRESS, + BUILTIN_RINT, + BUILTIN_ROUND, + BUILTIN_ROUNDEVEN, + BUILTIN_SAT_ADD, + BUILTIN_SAT_SHL, + BUILTIN_SAT_SUB, + BUILTIN_SCATTER, + BUILTIN_SELECT, + BUILTIN_SET_ROUNDING_MODE, + BUILTIN_STR_HASH, + BUILTIN_STR_UPPER, + BUILTIN_STR_LOWER, + BUILTIN_STR_FIND, + BUILTIN_SWIZZLE, + BUILTIN_SWIZZLE2, + BUILTIN_SIN, + BUILTIN_SQRT, + BUILTIN_SYSCALL, + BUILTIN_SYSCLOCK, + BUILTIN_TRAP, + BUILTIN_TRUNC, + BUILTIN_UNALIGNED_LOAD, + BUILTIN_UNALIGNED_STORE, + BUILTIN_UNREACHABLE, + BUILTIN_VECCOMPLT, + BUILTIN_VECCOMPLE, + BUILTIN_VECCOMPGT, + BUILTIN_VECCOMPGE, + BUILTIN_VECCOMPEQ, + BUILTIN_VECCOMPNE, + BUILTIN_VOLATILE_LOAD, + BUILTIN_VOLATILE_STORE, + BUILTIN_WASM_MEMORY_SIZE, + BUILTIN_WASM_MEMORY_GROW, + BUILTIN_NONE, + NUMBER_OF_BUILTINS = BUILTIN_NONE, + +// Disabled for now! + BUILTIN_LLRINT, + BUILTIN_LLROUND, + BUILTIN_LRINT, + BUILTIN_LROUND, +} BuiltinFunction; + +typedef enum +{ + CALL_C, + CALL_X64_VECTOR, + CALL_AAPCS, + CALL_AAPCS_VFP, +} CallABI; + +typedef enum +{ + CALL_ENV_GLOBAL_INIT, + CALL_ENV_FUNCTION, + CALL_ENV_FUNCTION_STATIC, + CALL_ENV_ATTR, +} CallEnvKind; typedef enum { @@ -144,6 +565,110 @@ typedef enum CAST_EXPVEC, } CastKind; +typedef enum +{ + CMP_LT = -1, + CMP_EQ = 0, + CMP_GT = 1, +} CmpRes; + +typedef enum +{ + COND_MISSING = -1, + COND_TRUE = 1, + COND_FALSE = 0, +} CondResult; + +typedef enum +{ + COND_TYPE_UNWRAP_BOOL, + COND_TYPE_UNWRAP, + COND_TYPE_EVALTYPE_VALUE, +} CondType; + +typedef enum +{ + CONSTANT_EVAL_NO_SIDE_EFFECTS, + CONSTANT_EVAL_GLOBAL_INIT, + CONSTANT_EVAL_LOCAL_INIT, + CONSTANT_EVAL_CONSTANT_VALUE, +} ConstantEvalKind; + +typedef enum +{ + CONST_INIT_ZERO, + CONST_INIT_STRUCT, + CONST_INIT_UNION, + CONST_INIT_VALUE, + CONST_INIT_ARRAY, + CONST_INIT_ARRAY_FULL, + CONST_INIT_ARRAY_VALUE, +} ConstInitType; + +typedef enum +{ + CONST_FLOAT, + CONST_INTEGER, + CONST_BOOL, + CONST_ENUM, + CONST_ERR, + CONST_BYTES, + CONST_STRING, + CONST_POINTER, + CONST_TYPEID, + CONST_INITIALIZER, + CONST_UNTYPED_LIST, + CONST_MEMBER, +} ConstKind; + +typedef enum +{ + CONTRACT_UNKNOWN, + CONTRACT_PURE, + CONTRACT_REQUIRE, + CONTRACT_PARAM, + CONTRACT_OPTIONALS, + CONTRACT_ENSURE, +} ContractKind; + +typedef enum +{ + CONV_NO = -1, + CONV_VOID = 0, + CONV_WILDCARD, + CONV_BOOL, + CONV_INT, + CONV_FLOAT, + CONV_POINTER, + CONV_SLICE, + CONV_VECTOR, + CONV_BITSTRUCT, + CONV_DISTINCT, + CONV_ARRAY, + CONV_STRUCT, + CONV_UNION, + CONV_ANY, + CONV_INTERFACE, + CONV_FAULT, + CONV_ENUM, + CONV_FUNC, + CONV_TYPEID, + CONV_ANYFAULT, + CONV_VOIDPTR, + CONV_VAPTR, + CONV_INFERRED, + CONV_UNTYPED_LIST, + CONV_LAST = CONV_UNTYPED_LIST +} ConvGroup; + + +typedef enum +{ + CTYPE_SHORT, + CTYPE_INT, + CTYPE_LONG, + CTYPE_LONG_LONG +} CType; typedef enum { @@ -176,56 +701,45 @@ typedef enum DECL_VAR, } DeclKind; -#define NON_TYPE_DECLS DECL_IMPORT: case DECL_MACRO: \ - case DECL_DECLARRAY: case DECL_ATTRIBUTE: case DECL_LABEL: \ - case DECL_DEFINE: case DECL_CT_ASSERT: case DECL_CT_EXEC: \ - case DECL_CT_ECHO: case DECL_CT_INCLUDE: case DECL_GLOBALS: \ - case DECL_BODYPARAM: case DECL_VAR: case DECL_ENUM_CONSTANT: case DECL_FAULTVALUE: \ - case DECL_POISONED - - -#define NON_RUNTIME_EXPR EXPR_POISONED: \ - case EXPR_CT_DEFINED: case EXPR_CT_AND_OR:\ - case EXPR_CT_CASTABLE: case EXPR_CT_IS_CONST: \ - case EXPR_CT_ARG: case EXPR_TYPEINFO: case EXPR_CT_IDENT: case EXPR_HASH_IDENT: \ - case EXPR_COMPILER_CONST: case EXPR_CT_CALL: \ - case EXPR_ANYSWITCH: case EXPR_STRINGIFY: case EXPR_TAGOF: \ - case EXPR_CT_EVAL: case EXPR_CT_CONCAT: case EXPR_CT_APPEND +typedef enum +{ + DEFINE_IDENT_ALIAS, + DEFINE_IDENT_GENERIC, +} DefineType; typedef enum { - CONTRACT_UNKNOWN, - CONTRACT_PURE, - CONTRACT_REQUIRE, - CONTRACT_PARAM, - CONTRACT_OPTIONALS, - CONTRACT_ENSURE, -} ContractKind; + DESIGNATOR_FIELD, + DESIGNATOR_ARRAY, + DESIGNATOR_RANGE +} DesignatorType; typedef enum { - INTROSPECT_TYPE_VOID = 0, - INTROSPECT_TYPE_BOOL = 1, - INTROSPECT_TYPE_SIGNED_INT = 2, - INTROSPECT_TYPE_UNSIGNED_INT = 3, - INTROSPECT_TYPE_FLOAT = 4, - INTROSPECT_TYPE_TYPEID = 5, - INTROSPECT_TYPE_ANYFAULT = 6, - INTROSPECT_TYPE_ANY = 7, - INTROSPECT_TYPE_ENUM = 8, - INTROSPECT_TYPE_FAULT = 9, - INTROSPECT_TYPE_STRUCT = 10, - INTROSPECT_TYPE_UNION = 11, - INTROSPECT_TYPE_BITSTRUCT = 12, - INTROSPECT_TYPE_FUNC = 13, - INTROSPECT_TYPE_OPTIONAL = 14, - INTROSPECT_TYPE_ARRAY = 15, - INTROSPECT_TYPE_SLICE = 16, - INTROSPECT_TYPE_VECTOR = 17, - INTROSPECT_TYPE_DISTINCT = 18, - INTROSPECT_TYPE_POINTER = 19, - INTROSPECT_TYPE_INTERFACE = 20, -} IntrospectType; + ENV_TYPE_UNKNOWN, + ENV_TYPE_GNU, + ENV_TYPE_GNUABIN32, + ENV_TYPE_GNUABI64, + ENV_TYPE_GNUEABI, + ENV_TYPE_GNUEABIHF, + ENV_TYPE_GNUX32, + ENV_TYPE_CODE16, + ENV_TYPE_EABI, + ENV_TYPE_EABIHF, + ENV_TYPE_ELFV1, + ENV_TYPE_ELFV2, + ENV_TYPE_ANDROID, + ENV_TYPE_MUSL, + ENV_TYPE_MUSLEABI, + ENV_TYPE_MUSLEABIHF, + ENV_TYPE_MSVC, + ENV_TYPE_ITANIUM, + ENV_TYPE_CYGNUS, + ENV_TYPE_CORECLR, + ENV_TYPE_SIMULATOR, + ENV_TYPE_MACABI, + ENV_TYPE_LAST = ENV_TYPE_MACABI +} EnvironmentType; typedef enum { @@ -302,72 +816,139 @@ typedef enum EXPR_LAST = EXPR_VASPLAT } ExprKind; -static_assert(EXPR_LAST < 128, "Too many expression types"); +typedef enum +{ + FLOAT_ABI_NONE, + FLOAT_ABI_SOFT, + FLOAT_ABI_HARD, +} FloatABI; typedef enum { - ASM_ARG_REG, - ASM_ARG_ADDR, - ASM_ARG_REGVAR, - ASM_ARG_ADDROF, - ASM_ARG_MEMVAR, - ASM_ARG_VALUE, - ASM_ARG_INT, -} AsmArgKind; + INOUT_ANY, + INOUT_IN, + INOUT_OUT, + INOUT_INOUT, +} InOutModifier; typedef enum { - ASM_REG_INT, - ASM_REG_FLOAT, - ASM_REG_IVEC, - ASM_REF_FVEC, -} AsmRegisterType; - -typedef enum FLAG_ATTR -{ - ARG_BITS_8 = 1 << 0, - ARG_BITS_16 = 1 << 1, - ARG_BITS_32 = 1 << 2, - ARG_BITS_64 = 1 << 3, - ARG_BITS_128 = 1 << 4, - ARG_BITS_256 = 1 << 5, - ARG_BITS_512 = 1 << 6, - ARG_BITS_80 = 1 << 7, -} AsmArgBits; + INTROSPECT_TYPE_VOID = 0, + INTROSPECT_TYPE_BOOL = 1, + INTROSPECT_TYPE_SIGNED_INT = 2, + INTROSPECT_TYPE_UNSIGNED_INT = 3, + INTROSPECT_TYPE_FLOAT = 4, + INTROSPECT_TYPE_TYPEID = 5, + INTROSPECT_TYPE_ANYFAULT = 6, + INTROSPECT_TYPE_ANY = 7, + INTROSPECT_TYPE_ENUM = 8, + INTROSPECT_TYPE_FAULT = 9, + INTROSPECT_TYPE_STRUCT = 10, + INTROSPECT_TYPE_UNION = 11, + INTROSPECT_TYPE_BITSTRUCT = 12, + INTROSPECT_TYPE_FUNC = 13, + INTROSPECT_TYPE_OPTIONAL = 14, + INTROSPECT_TYPE_ARRAY = 15, + INTROSPECT_TYPE_SLICE = 16, + INTROSPECT_TYPE_VECTOR = 17, + INTROSPECT_TYPE_DISTINCT = 18, + INTROSPECT_TYPE_POINTER = 19, + INTROSPECT_TYPE_INTERFACE = 20, +} IntrospectType; typedef enum { - TYPEID_INFO_KIND, - TYPEID_INFO_PARENTOF, - TYPEID_INFO_INNER, - TYPEID_INFO_LEN, - TYPEID_INFO_SIZEOF, - TYPEID_INFO_NAMES, -} TypeIdInfoKind; + LEX_NORMAL, + LEX_DOCS, +} LexMode; typedef enum { - CONST_FLOAT, - CONST_INTEGER, - CONST_BOOL, - CONST_ENUM, - CONST_ERR, - CONST_BYTES, - CONST_STRING, - CONST_POINTER, - CONST_TYPEID, - CONST_INITIALIZER, - CONST_UNTYPED_LIST, - CONST_MEMBER, -} ConstKind; + LINKER_LINK_EXE, + LINKER_LD, + LINKER_LD64, + LINKER_WASM, + LINKER_CC, + LINKER_UNKNOWN +} Linker; typedef enum { - DESIGNATOR_FIELD, - DESIGNATOR_ARRAY, - DESIGNATOR_RANGE -} DesignatorType; + MAIN_TYPE_ERROR, + MAIN_TYPE_RAW, + MAIN_TYPE_NO_ARGS, + MAIN_TYPE_ARGS, + MAIN_TYPE_WIN, +} MainType; +typedef enum +{ + METHOD_SEARCH_SUBMODULE_CURRENT, + METHOD_SEARCH_IMPORTED, + METHOD_SEARCH_CURRENT, + METHOD_SEARCH_PRIVATE_IMPORTED +} MethodSearchType; + +typedef enum +{ + OBJ_FORMAT_UNSUPPORTED, + OBJ_FORMAT_COFF, + OBJ_FORMAT_GOFF, + OBJ_FORMAT_ELF, + OBJ_FORMAT_MACHO, + OBJ_FORMAT_WASM, + OBJ_FORMAT_XCOFF, + OBJ_FORMAT_AOUT, +} ObjectFormatType; + +typedef enum +{ + OVERLOAD_ELEMENT_AT = 1, + OVERLOAD_ELEMENT_REF, + OVERLOAD_ELEMENT_SET, + OVERLOAD_LEN, +} OperatorOverload; + +typedef enum +{ + OS_TYPE_UNKNOWN, + OS_TYPE_NONE, + OS_TYPE_ANANAS, + OS_TYPE_CLOUD_ABI, + OS_TYPE_DRAGON_FLY, + OS_TYPE_FREE_BSD, + OS_TYPE_FUCHSIA, + OS_TYPE_IOS, + OS_TYPE_KFREEBSD, + OS_TYPE_LINUX, + OS_TYPE_PS3, + OS_TYPE_MACOSX, + OS_TYPE_NETBSD, + OS_TYPE_OPENBSD, + OS_TYPE_SOLARIS, + OS_TYPE_WIN32, + OS_TYPE_HAIKU, + OS_TYPE_MINIX, + OS_TYPE_RTEMS, + OS_TYPE_NACL, // Native Client + OS_TYPE_CNK, // BG/P Compute-Node Kernel + OS_TYPE_AIX, + OS_TYPE_CUDA, + OS_TYPE_NVOPENCL, + OS_TYPE_AMDHSA, + OS_TYPE_PS4, + OS_TYPE_ELFIAMCU, + OS_TYPE_TVOS, + OS_TYPE_WATCHOS, + OS_TYPE_MESA3D, + OS_TYPE_CONTIKI, + OS_TYPE_AMDPAL, + OS_TYPE_HERMITCORE, + OS_TYPE_HURD, + OS_TYPE_WASI, + OS_TYPE_EMSCRIPTEN, + OS_TYPE_LAST = OS_TYPE_EMSCRIPTEN +} OsType; typedef enum @@ -375,10 +956,10 @@ typedef enum PREC_NONE, PREC_ASSIGNMENT, // =, *=, /=, %=, +=, etc PREC_TERNARY, // ?: ? ?? - PREC_OR, // || - PREC_AND, // && + PREC_OR, // || ||| + PREC_AND, // && &&& PREC_RELATIONAL, // < > <= >= == != - PREC_ADDITIVE, // + - + PREC_ADDITIVE, // + - +++ PREC_BIT, // ^ | & PREC_SHIFT, // << >> PREC_MULTIPLICATIVE, // * / % @@ -387,6 +968,29 @@ typedef enum PREC_PRIMARY, } Precedence; +typedef enum +{ + PRINT_TYPE_ERROR, + PRINT_TYPE_NOTE, + PRINT_TYPE_WARN +} PrintType; + +typedef enum +{ + RESOLVE_NOT_DONE = 0, + RESOLVE_RUNNING, + RESOLVE_DONE +} ResolveStatus; + +typedef enum +{ + RESOLVE_TYPE_DEFAULT, + RESOLVE_TYPE_ALLOW_INFER = 0x01, + RESOLVE_TYPE_ALLOW_FLEXIBLE = 0x02, + RESOLVE_TYPE_MACRO_METHOD = RESOLVE_TYPE_ALLOW_INFER, + RESOLVE_TYPE_FUNC_METHOD = RESOLVE_TYPE_DEFAULT +} ResolveTypeKind; + typedef enum FLAG_ATTR { SCOPE_NONE = 0, @@ -399,28 +1003,20 @@ typedef enum FLAG_ATTR typedef enum { - RESOLVE_NOT_DONE = 0, - RESOLVE_RUNNING, - RESOLVE_DONE -} ResolveStatus; + STORAGE_NORMAL, + STORAGE_VOID, + STORAGE_COMPILE_TIME, + STORAGE_WILDCARD, + STORAGE_UNKNOWN +} StorageType; typedef enum { - TYPE_INFO_POISON, - TYPE_INFO_IDENTIFIER, - TYPE_INFO_CT_IDENTIFIER, - TYPE_INFO_TYPEOF, - TYPE_INFO_VATYPE, - TYPE_INFO_EVALTYPE, - TYPE_INFO_TYPEFROM, - TYPE_INFO_ARRAY, - TYPE_INFO_VECTOR, - TYPE_INFO_INFERRED_ARRAY, - TYPE_INFO_INFERRED_VECTOR, - TYPE_INFO_SLICE, - TYPE_INFO_POINTER, - TYPE_INFO_GENERIC, -} TypeInfoKind; + SUBSCRIPT_EVAL_VALUE, + SUBSCRIPT_EVAL_REF, + SUBSCRIPT_EVAL_ASSIGN, + SUBSCRIPT_EVAL_VALID, +} SubscriptEval; typedef enum { @@ -648,17 +1244,53 @@ typedef enum TOKEN_LAST = TOKEN_EOF, } TokenType; -#define NON_VOID_TYPE_TOKENS \ - TOKEN_BOOL: case TOKEN_CHAR: case TOKEN_DOUBLE: case TOKEN_FLOAT: \ - case TOKEN_FLOAT16: case TOKEN_BFLOAT: case TOKEN_INT128: case TOKEN_ICHAR: case TOKEN_INT: \ - case TOKEN_IPTR: case TOKEN_LONG: \ - case TOKEN_SHORT: case TOKEN_UINT128: case TOKEN_UINT: case TOKEN_ULONG: \ - case TOKEN_UPTR: case TOKEN_USHORT: case TOKEN_USZ: \ - case TOKEN_ISZ: case TOKEN_FLOAT128: case TOKEN_TYPEID: case TOKEN_ANYFAULT: case TOKEN_ANY -#define TYPE_TOKENS NON_VOID_TYPE_TOKENS: case TOKEN_VOID -#define CT_TYPE_TOKENS TOKEN_CT_TYPE_IDENT: case TOKEN_CT_TYPEOF: case TOKEN_CT_EVALTYPE: \ - case TOKEN_CT_VATYPE: case TOKEN_CT_TYPEFROM -#define TYPELIKE_TOKENS TYPE_TOKENS: case TOKEN_TYPE_IDENT: case CT_TYPE_TOKENS +typedef enum +{ + TYPE_MISMATCH = 0, + TYPE_SAME = 1, + TYPE_SAME_INT_SIZE = 2, + TYPE_ALIGNMENT_INCREASE = 3, + TYPE_ERROR = -1, +} TypeCmpResult; + +typedef enum +{ + TYPEID_INFO_KIND, + TYPEID_INFO_PARENTOF, + TYPEID_INFO_INNER, + TYPEID_INFO_LEN, + TYPEID_INFO_SIZEOF, + TYPEID_INFO_NAMES, +} TypeIdInfoKind; + +typedef enum +{ + TYPE_COMPRESSED_NONE = 0, + TYPE_COMPRESSED_PTR = 1, + TYPE_COMPRESSED_SUB = 2, + TYPE_COMPRESSED_SUBPTR = 3, + TYPE_COMPRESSED_PTRPTR = 4, + TYPE_COMPRESSED_PTRSUB = 5, + TYPE_COMPRESSED_SUBSUB = 6, +} TypeInfoCompressedKind; + +typedef enum +{ + TYPE_INFO_POISON, + TYPE_INFO_IDENTIFIER, + TYPE_INFO_CT_IDENTIFIER, + TYPE_INFO_TYPEOF, + TYPE_INFO_VATYPE, + TYPE_INFO_EVALTYPE, + TYPE_INFO_TYPEFROM, + TYPE_INFO_ARRAY, + TYPE_INFO_VECTOR, + TYPE_INFO_INFERRED_ARRAY, + TYPE_INFO_INFERRED_VECTOR, + TYPE_INFO_SLICE, + TYPE_INFO_POINTER, + TYPE_INFO_GENERIC, +} TypeInfoKind; // Note that ordering matters here. If ordering is changed, // So must type_find_max_type and friends. @@ -724,17 +1356,37 @@ typedef enum TYPE_LAST = TYPE_MEMBER } TypeKind; -#define FLATTENED_TYPES TYPE_DISTINCT: case TYPE_OPTIONAL: case TYPE_TYPEDEF -#define LOWERED_TYPES CT_TYPES: case TYPE_ENUM: case TYPE_TYPEDEF: case TYPE_TYPEID: \ - case TYPE_DISTINCT: case TYPE_ANYFAULT: case TYPE_FAULTTYPE: case TYPE_BITSTRUCT: \ - case TYPE_OPTIONAL: case TYPE_INTERFACE -#define CT_TYPES TYPE_TYPEINFO: case TYPE_INFERRED_ARRAY: case TYPE_INFERRED_VECTOR: case TYPE_UNTYPED_LIST: \ -case TYPE_POISONED: case TYPE_MEMBER: case TYPE_WILDCARD -#define ALL_INTS TYPE_I8: case TYPE_I16: case TYPE_I32: case TYPE_I64: case TYPE_I128: \ -case TYPE_U8: case TYPE_U16: case TYPE_U32: case TYPE_U64: case TYPE_U128 -#define ALL_SIGNED_INTS TYPE_I8: case TYPE_I16: case TYPE_I32: case TYPE_I64: case TYPE_I128 -#define ALL_UNSIGNED_INTS TYPE_U8: case TYPE_U16: case TYPE_U32: case TYPE_U64: case TYPE_U128 -#define ALL_FLOATS TYPE_BF16: case TYPE_F16: case TYPE_F32: case TYPE_F64: case TYPE_F128 +typedef enum +{ + TYPE_PROPERTY_ALIGNOF, + TYPE_PROPERTY_ASSOCIATED, + TYPE_PROPERTY_ELEMENTS, + TYPE_PROPERTY_EXTNAMEOF, + TYPE_PROPERTY_INF, + TYPE_PROPERTY_IS_EQ, + TYPE_PROPERTY_IS_ORDERED, + TYPE_PROPERTY_IS_SUBSTRUCT, + TYPE_PROPERTY_LEN, + TYPE_PROPERTY_MAX, + TYPE_PROPERTY_MEMBERSOF, + TYPE_PROPERTY_METHODSOF, + TYPE_PROPERTY_MIN, + TYPE_PROPERTY_NAN, + TYPE_PROPERTY_INNER, + TYPE_PROPERTY_KINDOF, + TYPE_PROPERTY_NAMES, + TYPE_PROPERTY_NAMEOF, + TYPE_PROPERTY_PARAMS, + TYPE_PROPERTY_PARENTOF, + TYPE_PROPERTY_QNAMEOF, + TYPE_PROPERTY_RETURNS, + TYPE_PROPERTY_SIZEOF, + TYPE_PROPERTY_TAGOF, + TYPE_PROPERTY_HAS_TAGOF, + TYPE_PROPERTY_VALUES, + TYPE_PROPERTY_NONE, + NUMBER_OF_TYPE_PROPERTIES = TYPE_PROPERTY_NONE +} TypeProperty; typedef enum { @@ -771,6 +1423,35 @@ typedef enum VARDECL_LAST_CT = VARDECL_LOCAL_CT_TYPE, } VarDeclKind; +typedef enum +{ + VARIADIC_NONE, + VARIADIC_TYPED, + VARIADIC_ANY, + VARIADIC_RAW, +} Variadic; + +typedef enum +{ + VENDOR_UNKNOWN, + VENDOR_APPLE, + VENDOR_PC, + VENDOR_SCEI, + VENDOR_BGP, + VENDOR_BGQ, + VENDOR_FREESCALE, + VENDOR_IBM, + VENDOR_IMAGINATION_TECHNOLOGIES, + VENDOR_MIPS_TECHNOLOGIES, + VENDOR_NVIDIA, + VENDOR_CSR, + VENDOR_MYRIAD, + VENDOR_AMD, + VENDOR_MESA, + VENDOR_SUSE, + VENDOR_OPEN_EMBEDDED, + VENDOR_LAST = VENDOR_OPEN_EMBEDDED +} VendorType; typedef enum { @@ -779,361 +1460,188 @@ typedef enum VISIBLE_LOCAL, } Visibility; -typedef enum FLAG_ATTR AttributeDomain_ -{ - ATTR_FUNC = 1 << 0, - ATTR_GLOBAL = 1 << 1, - ATTR_LOCAL = 1 << 2, - ATTR_ENUM = 1 << 3, - ATTR_STRUCT = 1 << 4, - ATTR_UNION = 1 << 5, - ATTR_CONST = 1 << 6, - ATTR_FAULT = 1 << 7, - ATTR_DEF = 1 << 8, - ATTR_MEMBER = 1 << 9, - ATTR_BITSTRUCT_MEMBER = 1 << 10, - ATTR_INTERFACE = 1 << 11, - ATTR_CALL = 1 << 12, - ATTR_BITSTRUCT = 1 << 13, - ATTR_MACRO = 1 << 14, - ATTR_DISTINCT = 1 << 15, - ATTR_ENUM_VALUE = 1 << 16, - ATTR_INTERFACE_METHOD = 1 << 17, - ATTR_PARAM = 1 << 18, -} AttributeDomain; - typedef enum { - OVERLOAD_ELEMENT_AT = 1, - OVERLOAD_ELEMENT_REF, - OVERLOAD_ELEMENT_SET, - OVERLOAD_LEN, -} OperatorOverload; + X86_FEAT_ADX, + X86_FEAT_AES, + X86_FEAT_AMX_BF16, + X86_FEAT_AMX_COMPLEX, + X86_FEAT_AMX_FP16, + X86_FEAT_AMX_INT8, + X86_FEAT_AMX_TILE, + X86_FEAT_AVX, + X86_FEAT_AVX10_1_512, + X86_FEAT_AVX10_1_256, + X86_FEAT_AVX2, + X86_FEAT_AVX5124FMAPS, + X86_FEAT_AVX5124VNNIW, + X86_FEAT_AVX512BF16, + X86_FEAT_AVX512BITALG, + X86_FEAT_AVX512BW, + X86_FEAT_AVX512CD, + X86_FEAT_AVX512DQ, + X86_FEAT_AVX512ER, + X86_FEAT_AVX512F, + X86_FEAT_AVX512FP16, + X86_FEAT_AVX512IFMA, + X86_FEAT_AVX512PF, + X86_FEAT_AVX512VBMI, + X86_FEAT_AVX512VBMI2, + X86_FEAT_AVX512VL, + X86_FEAT_AVX512VNNI, + X86_FEAT_AVX512VP2INTERSECT, + X86_FEAT_AVX512VPOPCNTDQ, + X86_FEAT_AVXIFMA, + X86_FEAT_AVXNECONVERT, + X86_FEAT_AVXVNNI, + X86_FEAT_AVXVNNIINT16, + X86_FEAT_AVXVNNIINT8, + X86_FEAT_BMI, + X86_FEAT_BMI2, + X86_FEAT_CLDEMOTE, + X86_FEAT_CLFLUSHOPT, + X86_FEAT_CLWB, + X86_FEAT_CLZERO, + X86_FEAT_CMOV, + X86_FEAT_CMPCCXADD, + X86_FEAT_CMPXCHG16B, + X86_FEAT_CMPXCHG8B, + X86_FEAT_CRC32, + X86_FEAT_ENQCMD, + X86_FEAT_EVEX512, + X86_FEAT_F16C, + X86_FEAT_FMA, + X86_FEAT_FMA4, + X86_FEAT_FSGSBASE, + X86_FEAT_FXSR, + X86_FEAT_GFNI, + X86_FEAT_HRESET, + X86_FEAT_INVPCID, + X86_FEAT_KL, + X86_FEAT_LWP, + X86_FEAT_LZCNT, + X86_FEAT_MMX, + X86_FEAT_MOVBE, + X86_FEAT_MOVDIR64B, + X86_FEAT_MOVDIRI, + X86_FEAT_MWAITX, + X86_FEAT_PCLMUL, + X86_FEAT_PCONFIG, + X86_FEAT_PKU, + X86_FEAT_POPCNT, + X86_FEAT_PREFETCHI, + X86_FEAT_PREFETCHWT1, + X86_FEAT_PRFCHW, + X86_FEAT_PTWRITE, + X86_FEAT_RAOINT, + X86_FEAT_RDPID, + X86_FEAT_RDPRU, + X86_FEAT_RDRND, + X86_FEAT_RDSEED, + X86_FEAT_RTM, + X86_FEAT_SAHF, + X86_FEAT_SERIALIZE, + X86_FEAT_SGX, + X86_FEAT_SHA, + X86_FEAT_SHA512, + X86_FEAT_SHSTK, + X86_FEAT_SM3, + X86_FEAT_SM4, + X86_FEAT_SSE, + X86_FEAT_SSE2, + X86_FEAT_SSE3, + X86_FEAT_SSE4_1, + X86_FEAT_SSE4_2, + X86_FEAT_SSE4_A, + X86_FEAT_SSSE3, + X86_FEAT_TBM, + X86_FEAT_TSXLDTRK, + X86_FEAT_UINTR, + X86_FEAT_USERMSR, + X86_FEAT_VAES, + X86_FEAT_VPCLMULQDQ, + X86_FEAT_VZEROUPPER, + X86_FEAT_WAITPKG, + X86_FEAT_WBNOINVD, + X86_FEAT_WIDEKL, + X86_FEAT_X87, + X86_FEAT_XOP, + X86_FEAT_XSAVE, + X86_FEAT_XSAVEC, + X86_FEAT_XSAVEOPT, + X86_FEAT_XSAVES, + X86_FEATURE_LAST = X86_FEAT_XSAVES, +} X86Feature; -typedef enum -{ - ATTRIBUTE_ALIGN, - ATTRIBUTE_BENCHMARK, - ATTRIBUTE_BIGENDIAN, - ATTRIBUTE_BUILTIN, - ATTRIBUTE_CALLCONV, - ATTRIBUTE_COMPACT, - ATTRIBUTE_CONST, - ATTRIBUTE_DEPRECATED, - ATTRIBUTE_DYNAMIC, - ATTRIBUTE_EXPORT, - ATTRIBUTE_EXTERN, - ATTRIBUTE_FINALIZER, - ATTRIBUTE_IF, - ATTRIBUTE_INLINE, - ATTRIBUTE_INIT, - ATTRIBUTE_LINK, - ATTRIBUTE_LITTLEENDIAN, - ATTRIBUTE_LOCAL, - ATTRIBUTE_MAYDISCARD, - ATTRIBUTE_NAKED, - ATTRIBUTE_NOALIAS, - ATTRIBUTE_NODISCARD, - ATTRIBUTE_NOINIT, - ATTRIBUTE_NOINLINE, - ATTRIBUTE_NOPADDING, - ATTRIBUTE_NORETURN, - ATTRIBUTE_NOSTRIP, - ATTRIBUTE_OBFUSCATE, - ATTRIBUTE_OPERATOR, - ATTRIBUTE_OPTIONAL, - ATTRIBUTE_OVERLAP, - ATTRIBUTE_PACKED, - ATTRIBUTE_PRIVATE, - ATTRIBUTE_PUBLIC, - ATTRIBUTE_PURE, - ATTRIBUTE_REFLECT, - ATTRIBUTE_SAFEMACRO, - ATTRIBUTE_SECTION, - ATTRIBUTE_TAG, - ATTRIBUTE_TEST, - ATTRIBUTE_UNUSED, - ATTRIBUTE_USED, - ATTRIBUTE_WASM, - ATTRIBUTE_WEAK, - ATTRIBUTE_WINMAIN, - ATTRIBUTE_NONE, - NUMBER_OF_ATTRIBUTES = ATTRIBUTE_NONE, -} AttributeType; +// -- Arch helper macros +#define ARCH_UNSUPPORTED ARCH_TYPE_AARCH64_32: case ARCH_TYPE_BPFEL: case ARCH_TYPE_BPFEB: case ARCH_TYPE_SPARCEL: \ + case ARCH_TYPE_LE64: case ARCH_TYPE_AMDIL: case ARCH_TYPE_AMDIL64: case ARCH_TYPE_HSAIL: case ARCH_TYPE_HSAIL64: \ + case ARCH_TYPE_KALIMBA: case ARCH_TYPE_SHAVE: case ARCH_TYPE_RSCRIPT32: case ARCH_TYPE_RSCRIPT64: \ + case ARCH_TYPE_LE32: case ARCH_TYPE_MIPS: case ARCH_TYPE_MIPSEL: case ARCH_TYPE_MIPS64EL: case ARCH_TYPE_MIPS64: \ + case ARCH_TYPE_AVR: case ARCH_TYPE_NVPTX64: case ARCH_TYPE_NVPTX: case ARCH_TYPE_MSP430: case ARCH_TYPE_SYSTEMZ: \ + case ARCH_TYPE_TCELE: case ARCH_TYPE_TCE: case ARCH_TYPE_LANAI: case ARCH_TYPE_HEXAGON: case ARCH_TYPE_AMDGCN: \ + case ARCH_TYPE_R600: case ARCH_TYPE_SPARC: case ARCH_TYPE_SPARCV9: case ARCH_TYPE_XCORE: case ARCH_TYPE_ARC: \ + case ARCH_TYPE_SPIR64: case ARCH_TYPE_SPIR +// -- AST helper macros +#define CT_AST \ + AST_CT_ASSERT: case AST_CT_ECHO_STMT: case AST_CT_ELSE_STMT: \ + case AST_CT_FOREACH_STMT: case AST_CT_FOR_STMT: \ + case AST_CT_IF_STMT: case AST_CT_SWITCH_STMT -typedef enum -{ - CALL_C, - CALL_X64_VECTOR, - CALL_AAPCS, - CALL_AAPCS_VFP, -} CallABI; +// -- Decl helper macros +#define NON_TYPE_DECLS DECL_IMPORT: case DECL_MACRO: \ + case DECL_DECLARRAY: case DECL_ATTRIBUTE: case DECL_LABEL: \ + case DECL_DEFINE: case DECL_CT_ASSERT: case DECL_CT_EXEC: \ + case DECL_CT_ECHO: case DECL_CT_INCLUDE: case DECL_GLOBALS: \ + case DECL_BODYPARAM: case DECL_VAR: case DECL_ENUM_CONSTANT: case DECL_FAULTVALUE: \ + case DECL_POISONED -typedef enum -{ - ANALYSIS_NOT_BEGUN, - ANALYSIS_MODULE_HIERARCHY, - ANALYSIS_MODULE_TOP, - ANALYSIS_IMPORTS, - ANALYSIS_REGISTER_GLOBAL_DECLARATIONS, - ANALYSIS_REGISTER_CONDITIONAL_UNITS, - ANALYSIS_REGISTER_CONDITIONAL_DECLARATIONS, - ANALYSIS_DECLS, - ANALYSIS_CT_ECHO, - ANALYSIS_CT_ASSERT, - ANALYSIS_FUNCTIONS, - ANALYSIS_INTERFACE, - ANALYSIS_FINALIZE, - ANALYSIS_LAST = ANALYSIS_FINALIZE -} AnalysisStage; +// -- Expr helper macros +#define NON_RUNTIME_EXPR EXPR_POISONED: \ + case EXPR_CT_DEFINED: case EXPR_CT_AND_OR:\ + case EXPR_CT_CASTABLE: case EXPR_CT_IS_CONST: \ + case EXPR_CT_ARG: case EXPR_TYPEINFO: case EXPR_CT_IDENT: case EXPR_HASH_IDENT: \ + case EXPR_COMPILER_CONST: case EXPR_CT_CALL: \ + case EXPR_ANYSWITCH: case EXPR_STRINGIFY: case EXPR_TAGOF: \ + case EXPR_CT_EVAL: case EXPR_CT_CONCAT: case EXPR_CT_APPEND -typedef enum -{ - BUILTIN_ABS, - BUILTIN_ANY_MAKE, - BUILTIN_ATOMIC_LOAD, - BUILTIN_ATOMIC_STORE, - BUILTIN_ATOMIC_FETCH_EXCHANGE, - BUILTIN_ATOMIC_FETCH_ADD, - BUILTIN_ATOMIC_FETCH_SUB, - BUILTIN_ATOMIC_FETCH_AND, - BUILTIN_ATOMIC_FETCH_NAND, - BUILTIN_ATOMIC_FETCH_OR, - BUILTIN_ATOMIC_FETCH_XOR, - BUILTIN_ATOMIC_FETCH_MAX, - BUILTIN_ATOMIC_FETCH_MIN, - BUILTIN_ATOMIC_FETCH_INC_WRAP, - BUILTIN_ATOMIC_FETCH_DEC_WRAP, - BUILTIN_BITREVERSE, - BUILTIN_BREAKPOINT, - BUILTIN_BSWAP, - BUILTIN_CEIL, - BUILTIN_COMPARE_EXCHANGE, - BUILTIN_COPYSIGN, - BUILTIN_COS, - BUILTIN_CTLZ, - BUILTIN_CTTZ, - BUILTIN_EXACT_ADD, - BUILTIN_EXACT_DIV, - BUILTIN_EXACT_MOD, - BUILTIN_EXACT_MUL, - BUILTIN_EXACT_NEG, - BUILTIN_EXACT_SUB, - BUILTIN_EXP, - BUILTIN_EXP2, - BUILTIN_EXPECT, - BUILTIN_EXPECT_WITH_PROBABILITY, - BUILTIN_FLOOR, - BUILTIN_FMA, - BUILTIN_FMULADD, - BUILTIN_FRAMEADDRESS, - BUILTIN_FSHL, - BUILTIN_FSHR, - BUILTIN_GATHER, - BUILTIN_GET_ROUNDING_MODE, - BUILTIN_LOG, - BUILTIN_LOG10, - BUILTIN_LOG2, - BUILTIN_MASKED_LOAD, - BUILTIN_MASKED_STORE, - BUILTIN_MAX, - BUILTIN_MEMCOPY, - BUILTIN_MEMCOPY_INLINE, - BUILTIN_MEMMOVE, - BUILTIN_MEMSET, - BUILTIN_MEMSET_INLINE, - BUILTIN_MIN, - BUILTIN_NEARBYINT, - BUILTIN_OVERFLOW_ADD, - BUILTIN_OVERFLOW_MUL, - BUILTIN_OVERFLOW_SUB, - BUILTIN_POPCOUNT, - BUILTIN_POW, - BUILTIN_POW_INT, - BUILTIN_PREFETCH, - BUILTIN_REDUCE_ADD, - BUILTIN_REDUCE_AND, - BUILTIN_REDUCE_FADD, - BUILTIN_REDUCE_FMUL, - BUILTIN_REDUCE_MAX, - BUILTIN_REDUCE_MIN, - BUILTIN_REDUCE_MUL, - BUILTIN_REDUCE_OR, - BUILTIN_REDUCE_XOR, - BUILTIN_REVERSE, - BUILTIN_RETURNADDRESS, - BUILTIN_RINT, - BUILTIN_ROUND, - BUILTIN_ROUNDEVEN, - BUILTIN_SAT_ADD, - BUILTIN_SAT_SHL, - BUILTIN_SAT_SUB, - BUILTIN_SCATTER, - BUILTIN_SELECT, - BUILTIN_SET_ROUNDING_MODE, - BUILTIN_STR_HASH, - BUILTIN_STR_UPPER, - BUILTIN_STR_LOWER, - BUILTIN_STR_FIND, - BUILTIN_SWIZZLE, - BUILTIN_SWIZZLE2, - BUILTIN_SIN, - BUILTIN_SQRT, - BUILTIN_SYSCALL, - BUILTIN_SYSCLOCK, - BUILTIN_TRAP, - BUILTIN_TRUNC, - BUILTIN_UNALIGNED_LOAD, - BUILTIN_UNALIGNED_STORE, - BUILTIN_UNREACHABLE, - BUILTIN_VECCOMPLT, - BUILTIN_VECCOMPLE, - BUILTIN_VECCOMPGT, - BUILTIN_VECCOMPGE, - BUILTIN_VECCOMPEQ, - BUILTIN_VECCOMPNE, - BUILTIN_VOLATILE_LOAD, - BUILTIN_VOLATILE_STORE, - BUILTIN_WASM_MEMORY_SIZE, - BUILTIN_WASM_MEMORY_GROW, - BUILTIN_NONE, - NUMBER_OF_BUILTINS = BUILTIN_NONE, +static_assert(EXPR_LAST < 128, "Too many expression types"); -// Disabled for now! - BUILTIN_LLRINT, - BUILTIN_LLROUND, - BUILTIN_LRINT, - BUILTIN_LROUND, -} BuiltinFunction; +// -- OsType helper macros +#define OS_DARWIN_TYPES OS_TYPE_WATCHOS: case OS_TYPE_IOS: case OS_TYPE_TVOS: case OS_TYPE_MACOSX +#define OS_UNSUPPORTED OS_TYPE_AIX: case OS_TYPE_HAIKU: case OS_TYPE_ANANAS: case OS_TYPE_CLOUD_ABI: \ + case OS_TYPE_DRAGON_FLY: case OS_TYPE_FUCHSIA: case OS_TYPE_KFREEBSD: case OS_TYPE_PS3: case OS_TYPE_RTEMS: \ + case OS_TYPE_SOLARIS: case OS_TYPE_MINIX: case OS_TYPE_NACL: case OS_TYPE_CNK: case OS_TYPE_CUDA: \ + case OS_TYPE_NVOPENCL: case OS_TYPE_AMDHSA: case OS_TYPE_PS4: case OS_TYPE_ELFIAMCU: case OS_TYPE_MESA3D: \ + case OS_TYPE_CONTIKI: case OS_TYPE_AMDPAL: case OS_TYPE_HERMITCORE: case OS_TYPE_HURD: case OS_TYPE_EMSCRIPTEN -typedef enum -{ - BUILTIN_DEF_DATE, - BUILTIN_DEF_FILE, - BUILTIN_DEF_FILEPATH, - BUILTIN_DEF_FUNC, - BUILTIN_DEF_FUNCTION, - BUILTIN_DEF_LINE, - BUILTIN_DEF_LINE_RAW, - BUILTIN_DEF_MODULE, - BUILTIN_DEF_BENCHMARK_NAMES, - BUILTIN_DEF_BENCHMARK_FNS, - BUILTIN_DEF_TEST_NAMES, - BUILTIN_DEF_TEST_FNS, - BUILTIN_DEF_TIME, - BUILTIN_DEF_NONE, - NUMBER_OF_BUILTIN_DEFINES = BUILTIN_DEF_NONE -} BuiltinDefine; +// Token helper macros -typedef enum -{ - TYPE_PROPERTY_ALIGNOF, - TYPE_PROPERTY_ASSOCIATED, - TYPE_PROPERTY_ELEMENTS, - TYPE_PROPERTY_EXTNAMEOF, - TYPE_PROPERTY_INF, - TYPE_PROPERTY_IS_EQ, - TYPE_PROPERTY_IS_ORDERED, - TYPE_PROPERTY_IS_SUBSTRUCT, - TYPE_PROPERTY_LEN, - TYPE_PROPERTY_MAX, - TYPE_PROPERTY_MEMBERSOF, - TYPE_PROPERTY_METHODSOF, - TYPE_PROPERTY_MIN, - TYPE_PROPERTY_NAN, - TYPE_PROPERTY_INNER, - TYPE_PROPERTY_KINDOF, - TYPE_PROPERTY_NAMES, - TYPE_PROPERTY_NAMEOF, - TYPE_PROPERTY_PARAMS, - TYPE_PROPERTY_PARENTOF, - TYPE_PROPERTY_QNAMEOF, - TYPE_PROPERTY_RETURNS, - TYPE_PROPERTY_SIZEOF, - TYPE_PROPERTY_TAGOF, - TYPE_PROPERTY_HAS_TAGOF, - TYPE_PROPERTY_VALUES, - TYPE_PROPERTY_NONE, - NUMBER_OF_TYPE_PROPERTIES = TYPE_PROPERTY_NONE -} TypeProperty; -typedef enum -{ - ATOMIC_NONE, - ATOMIC_UNORDERED, - ATOMIC_RELAXED, - ATOMIC_ACQUIRE, - ATOMIC_RELEASE, - ATOMIC_ACQUIRE_RELEASE, - ATOMIC_SEQ_CONSISTENT, -} Atomicity; +#define NON_VOID_TYPE_TOKENS \ + TOKEN_BOOL: case TOKEN_CHAR: case TOKEN_DOUBLE: case TOKEN_FLOAT: \ + case TOKEN_FLOAT16: case TOKEN_BFLOAT: case TOKEN_INT128: case TOKEN_ICHAR: case TOKEN_INT: \ + case TOKEN_IPTR: case TOKEN_LONG: \ + case TOKEN_SHORT: case TOKEN_UINT128: case TOKEN_UINT: case TOKEN_ULONG: \ + case TOKEN_UPTR: case TOKEN_USHORT: case TOKEN_USZ: \ + case TOKEN_ISZ: case TOKEN_FLOAT128: case TOKEN_TYPEID: case TOKEN_ANYFAULT: case TOKEN_ANY +#define TYPE_TOKENS NON_VOID_TYPE_TOKENS: case TOKEN_VOID +#define CT_TYPE_TOKENS TOKEN_CT_TYPE_IDENT: case TOKEN_CT_TYPEOF: case TOKEN_CT_EVALTYPE: \ + case TOKEN_CT_VATYPE: case TOKEN_CT_TYPEFROM +#define TYPELIKE_TOKENS TYPE_TOKENS: case TOKEN_TYPE_IDENT: case CT_TYPE_TOKENS +// -- Types helper macros +#define FLATTENED_TYPES TYPE_DISTINCT: case TYPE_OPTIONAL: case TYPE_TYPEDEF +#define ALL_SIGNED_INTS TYPE_I8: case TYPE_I16: case TYPE_I32: case TYPE_I64: case TYPE_I128 +#define ALL_UNSIGNED_INTS TYPE_U8: case TYPE_U16: case TYPE_U32: case TYPE_U64: case TYPE_U128 +#define ALL_FLOATS TYPE_BF16: case TYPE_F16: case TYPE_F32: case TYPE_F64: case TYPE_F128 -typedef enum -{ - LEX_NORMAL, - LEX_DOCS, -} LexMode; +#define LOWERED_TYPES CT_TYPES: case TYPE_ENUM: case TYPE_TYPEDEF: case TYPE_TYPEID: \ + case TYPE_DISTINCT: case TYPE_ANYFAULT: case TYPE_FAULTTYPE: case TYPE_BITSTRUCT: \ + case TYPE_OPTIONAL: case TYPE_INTERFACE -typedef enum -{ - PARAM_ANY, - PARAM_IN, - PARAM_OUT, - PARAM_INOUT, -} InOutModifier; +#define CT_TYPES TYPE_TYPEINFO: case TYPE_INFERRED_ARRAY: case TYPE_INFERRED_VECTOR: case TYPE_UNTYPED_LIST: \ +case TYPE_POISONED: case TYPE_MEMBER: case TYPE_WILDCARD -typedef enum -{ - CONSTANT_EVAL_NO_SIDE_EFFECTS, - CONSTANT_EVAL_GLOBAL_INIT, - CONSTANT_EVAL_LOCAL_INIT, - CONSTANT_EVAL_CONSTANT_VALUE, -} ConstantEvalKind; - -typedef enum -{ - COND_TYPE_UNWRAP_BOOL, - COND_TYPE_UNWRAP, - COND_TYPE_EVALTYPE_VALUE, -} CondType; - - -typedef enum -{ - MAIN_TYPE_ERROR, - MAIN_TYPE_RAW, - MAIN_TYPE_NO_ARGS, - MAIN_TYPE_ARGS, - MAIN_TYPE_WIN, -} MainType; - -typedef enum -{ - CONV_NO = -1, - CONV_VOID = 0, - CONV_WILDCARD, - CONV_BOOL, - CONV_INT, - CONV_FLOAT, - CONV_POINTER, - CONV_SLICE, - CONV_VECTOR, - CONV_BITSTRUCT, - CONV_DISTINCT, - CONV_ARRAY, - CONV_STRUCT, - CONV_UNION, - CONV_ANY, - CONV_INTERFACE, - CONV_FAULT, - CONV_ENUM, - CONV_FUNC, - CONV_TYPEID, - CONV_ANYFAULT, - CONV_VOIDPTR, - CONV_VAPTR, - CONV_INFERRED, - CONV_UNTYPED_LIST, - CONV_LAST = CONV_UNTYPED_LIST -} ConvGroup; +#define ALL_INTS TYPE_I8: case TYPE_I16: case TYPE_I32: case TYPE_I64: case TYPE_I128: \ +case TYPE_U8: case TYPE_U16: case TYPE_U32: case TYPE_U64: case TYPE_U128 \ No newline at end of file diff --git a/src/compiler/json_output.c b/src/compiler/json_output.c index f85146b0b..b1a3e49ac 100644 --- a/src/compiler/json_output.c +++ b/src/compiler/json_output.c @@ -18,14 +18,14 @@ static inline void emit_modules(FILE *file) { fputs("\t\"modules\": [\n", file); - FOREACH_IDX(i, Module *, module, global_context.module_list) + FOREACH_IDX(i, Module *, module, compiler.context.module_list) { if (i != 0) fputs(",\n", file); PRINTF("\t\t\"%s\"", module->name->module); } fputs("\n\t],\n", file); fputs("\t\"generic_modules\": [\n", file); - FOREACH_IDX(j, Module *, module, global_context.generic_module_list) + FOREACH_IDX(j, Module *, module, compiler.context.generic_module_list) { if (j != 0) fputs(",\n", file); PRINTF("\t\t\"%s\"", module->name->module); @@ -215,7 +215,7 @@ static inline void emit_types(FILE *file) fputs("\t\"types\": {\n", file); { bool first = true; - FOREACH_DECL(Decl *type, global_context.module_list) + FOREACH_DECL(Decl *type, compiler.context.module_list) if (!decl_is_user_defined_type(type) && type->decl_kind != DECL_TYPEDEF) continue; if (decl_is_hidden(type)) continue; INERT_COMMA; @@ -227,7 +227,7 @@ static inline void emit_types(FILE *file) fputs("\t\"generic_types\": {\n", file); { bool first = true; - FOREACH_DECL(Decl *type, global_context.generic_module_list) + FOREACH_DECL(Decl *type, compiler.context.generic_module_list) if (!decl_is_user_defined_type(type) && type->decl_kind != DECL_TYPEDEF) continue; if (decl_is_hidden(type)) continue; INERT_COMMA; @@ -242,7 +242,7 @@ static inline void emit_functions(FILE *file) fputs("\t\"functions\": {\n", file); { bool first = true; - FOREACH_DECL(Decl *func, global_context.module_list) + FOREACH_DECL(Decl *func, compiler.context.module_list) if (func->decl_kind != DECL_FUNC) continue; if (decl_is_hidden(func)) continue; INERT_COMMA; @@ -254,7 +254,7 @@ static inline void emit_functions(FILE *file) fputs("\t\"generic_functions\": {\n", file); { bool first = true; - FOREACH_DECL(Decl *func, global_context.generic_module_list) + FOREACH_DECL(Decl *func, compiler.context.generic_module_list) if (func->decl_kind != DECL_FUNC) continue; if (decl_is_hidden(func)) continue; INERT_COMMA; diff --git a/src/compiler/linker.c b/src/compiler/linker.c index d3b1425b1..68ee31ee6 100644 --- a/src/compiler/linker.c +++ b/src/compiler/linker.c @@ -5,17 +5,6 @@ #include #endif - -typedef enum -{ - LINKER_LINK_EXE, - LINKER_LD, - LINKER_LD64, - LINKER_WASM, - LINKER_CC, - LINKER_UNKNOWN -} Linker; - #define add_arg(arg_) vec_add(*args_ref, (arg_)) #define add_arg2(arg_, arg_2) vec_add(*args_ref, str_cat((arg_), (arg_2))) @@ -61,12 +50,12 @@ static const char *string_esc(const char *str) static void linker_setup_windows(const char ***args_ref, Linker linker_type) { - add_arg(active_target.win.use_win_subsystem ? "/SUBSYSTEM:WINDOWS" : "/SUBSYSTEM:CONSOLE"); - if (link_libc()) global_context_add_link("dbghelp"); + add_arg(compiler.build.win.use_win_subsystem ? "/SUBSYSTEM:WINDOWS" : "/SUBSYSTEM:CONSOLE"); + if (link_libc()) linking_add_link(&compiler.linking, "dbghelp"); if (linker_type == LINKER_CC) return; //add_arg("/MACHINE:X64"); bool is_debug = false; - switch (active_target.debug_info) + switch (compiler.build.debug_info) { case DEBUG_INFO_NOT_SET: break; @@ -88,8 +77,8 @@ static void linker_setup_windows(const char ***args_ref, Linker linker_type) // so we do not link with debug dll versions of libc. link_with_dynamic_debug_libc = false; #endif - WinCrtLinking linking = active_target.win.crt_linking; - FOREACH(Library *, library, active_target.library_list) + WinCrtLinking linking = compiler.build.win.crt_linking; + FOREACH(Library *, library, compiler.build.library_list) { WinCrtLinking wincrt = library->target_used->win_crt; if (wincrt == WIN_CRT_DEFAULT) continue; @@ -101,12 +90,12 @@ static void linker_setup_windows(const char ***args_ref, Linker linker_type) linking = wincrt; } - if (!active_target.win.sdk) + if (!compiler.build.win.sdk) { const char *path = windows_cross_compile_library(); if (path) { - switch (platform_target.arch) + switch (compiler.platform.arch) { case ARCH_TYPE_ARM: scratch_buffer_append("/arm"); @@ -125,20 +114,20 @@ static void linker_setup_windows(const char ***args_ref, Linker linker_type) } if (file_exists(scratch_buffer_to_string())) { - active_target.win.sdk = scratch_buffer_copy(); + compiler.build.win.sdk = scratch_buffer_copy(); // If we only use the msvc cross compile on windows, we // avoid linking with dynamic debug dlls. link_with_dynamic_debug_libc = false; } } } - if (active_target.win.def) + if (compiler.build.win.def) { - add_arg(str_printf("/def:%s", active_target.win.def)); + add_arg(str_printf("/def:%s", compiler.build.win.def)); } - if (active_target.win.sdk) + if (compiler.build.win.sdk) { - add_arg(str_printf("/LIBPATH:%s", active_target.win.sdk)); + add_arg(str_printf("/LIBPATH:%s", compiler.build.win.sdk)); } else { @@ -152,31 +141,31 @@ static void linker_setup_windows(const char ***args_ref, Linker linker_type) add_arg(str_printf("/LIBPATH:%s", windows_sdk->vs_library_path)); } // Do not link any. - if (active_target.win.crt_linking == WIN_CRT_NONE) return; + if (compiler.build.win.crt_linking == WIN_CRT_NONE) return; - global_context_add_link("kernel32"); - global_context_add_link("ntdll"); - global_context_add_link("user32"); - global_context_add_link("shell32"); - global_context_add_link("Shlwapi"); - global_context_add_link("Ws2_32"); - global_context_add_link("legacy_stdio_definitions"); + linking_add_link(&compiler.linking, "kernel32"); + linking_add_link(&compiler.linking, "ntdll"); + linking_add_link(&compiler.linking, "user32"); + linking_add_link(&compiler.linking, "shell32"); + linking_add_link(&compiler.linking, "Shlwapi"); + linking_add_link(&compiler.linking, "Ws2_32"); + linking_add_link(&compiler.linking, "legacy_stdio_definitions"); - if (active_target.win.crt_linking == WIN_CRT_STATIC) + if (compiler.build.win.crt_linking == WIN_CRT_STATIC) { if (is_debug) { - global_context_add_link("libucrtd"); - global_context_add_link("libvcruntimed"); - global_context_add_link("libcmtd"); - global_context_add_link("libcpmtd"); + linking_add_link(&compiler.linking, "libucrtd"); + linking_add_link(&compiler.linking, "libvcruntimed"); + linking_add_link(&compiler.linking, "libcmtd"); + linking_add_link(&compiler.linking, "libcpmtd"); } else { - global_context_add_link("libucrt"); - global_context_add_link("libvcruntime"); - global_context_add_link("libcmt"); - global_context_add_link("libcpmt"); + linking_add_link(&compiler.linking, "libucrt"); + linking_add_link(&compiler.linking, "libvcruntime"); + linking_add_link(&compiler.linking, "libcmt"); + linking_add_link(&compiler.linking, "libcpmt"); } } else @@ -185,17 +174,17 @@ static void linker_setup_windows(const char ***args_ref, Linker linker_type) // if so, then exclude them. if (is_debug && link_with_dynamic_debug_libc) { - global_context_add_link("ucrtd"); - global_context_add_link("vcruntimed"); - global_context_add_link("msvcrtd"); - global_context_add_link("msvcprtd"); + linking_add_link(&compiler.linking, "ucrtd"); + linking_add_link(&compiler.linking, "vcruntimed"); + linking_add_link(&compiler.linking, "msvcrtd"); + linking_add_link(&compiler.linking, "msvcprtd"); } else { - global_context_add_link("ucrt"); - global_context_add_link("vcruntime"); - global_context_add_link("msvcrt"); - global_context_add_link("msvcprt"); + linking_add_link(&compiler.linking, "ucrt"); + linking_add_link(&compiler.linking, "vcruntime"); + linking_add_link(&compiler.linking, "msvcrt"); + linking_add_link(&compiler.linking, "msvcprt"); } } add_arg("/NOLOGO"); @@ -206,12 +195,12 @@ static void linker_setup_macos(const char ***args_ref, Linker linker_type) if (linker_type == LINKER_CC) { add_arg("-target"); - add_arg(platform_target.target_triple); + add_arg(compiler.platform.target_triple); return; } add_arg("-arch"); - add_arg(arch_to_linker_arch(platform_target.arch)); - if (strip_unused() && active_target.type == TARGET_TYPE_EXECUTABLE) + add_arg(arch_to_linker_arch(compiler.platform.arch)); + if (strip_unused() && compiler.build.type == TARGET_TYPE_EXECUTABLE) { add_arg("-no_exported_symbols"); add_arg("-dead_strip"); @@ -220,33 +209,33 @@ static void linker_setup_macos(const char ***args_ref, Linker linker_type) // Skip if no libc. if (!link_libc()) return; - if (!active_target.macos.sdk) + if (!compiler.build.macos.sdk) { error_exit("Cannot crosslink MacOS without providing --macossdk."); } - global_context_add_link("System"); - global_context_add_link("m"); + linking_add_link(&compiler.linking, "System"); + linking_add_link(&compiler.linking, "m"); add_arg("-syslibroot"); - add_arg(active_target.macos.sysroot); - if (is_no_pie(platform_target.reloc_model)) add_arg("-no_pie"); - if (is_pie(platform_target.reloc_model)) add_arg("-pie"); + add_arg(compiler.build.macos.sysroot); + if (is_no_pie(compiler.platform.reloc_model)) add_arg("-no_pie"); + if (is_pie(compiler.platform.reloc_model)) add_arg("-pie"); add_arg("-platform_version"); add_arg("macos"); - if (active_target.macos.min_version) + if (compiler.build.macos.min_version) { - add_arg(active_target.macos.min_version); + add_arg(compiler.build.macos.min_version); } else { - add_arg(str_printf("%d.%d.0", active_target.macos.sdk->macos_min_deploy_target.major, active_target.macos.sdk->macos_min_deploy_target.minor)); + add_arg(str_printf("%d.%d.0", compiler.build.macos.sdk->macos_min_deploy_target.major, compiler.build.macos.sdk->macos_min_deploy_target.minor)); } - if (active_target.macos.sdk_version) + if (compiler.build.macos.sdk_version) { - add_arg(active_target.macos.sdk_version); + add_arg(compiler.build.macos.sdk_version); } else { - add_arg(str_printf("%d.%d", active_target.macos.sdk->macos_deploy_target.major, active_target.macos.sdk->macos_deploy_target.minor)); + add_arg(str_printf("%d.%d", compiler.build.macos.sdk->macos_deploy_target.major, compiler.build.macos.sdk->macos_deploy_target.minor)); } } @@ -270,8 +259,8 @@ static const char *find_arch_glob_path(const char *glob_path, int file_len) { const char *path = globbuf.gl_pathv[i]; // Avoid qemu problems - if (platform_target.arch != ARCH_TYPE_RISCV64 - && platform_target.arch != ARCH_TYPE_RISCV32 + if (compiler.platform.arch != ARCH_TYPE_RISCV64 + && compiler.platform.arch != ARCH_TYPE_RISCV32 && strstr(path, "riscv")) continue; size_t len = strlen(path); assert(len > file_len); @@ -286,7 +275,7 @@ static const char *find_arch_glob_path(const char *glob_path, int file_len) } static const char *find_linux_crt(void) { - if (active_target.linuxpaths.crt) return active_target.linuxpaths.crt; + if (compiler.build.linuxpaths.crt) return compiler.build.linuxpaths.crt; const char *path = find_arch_glob_path("/usr/lib/*/crt1.o", 6); if (!path) { @@ -299,7 +288,7 @@ static const char *find_linux_crt(void) static const char *find_linux_crt_begin(void) { - if (active_target.linuxpaths.crtbegin) return active_target.linuxpaths.crtbegin; + if (compiler.build.linuxpaths.crtbegin) return compiler.build.linuxpaths.crtbegin; const char *path = find_arch_glob_path("/usr/lib/gcc/*/*/crtbegin.o", 10); if (!path) { @@ -312,7 +301,7 @@ static const char *find_linux_crt_begin(void) static void linker_setup_linux(const char ***args_ref, Linker linker_type) { - global_context_add_link("dl"); + linking_add_link(&compiler.linking, "dl"); if (linker_type == LINKER_CC) { if (!link_libc()) @@ -322,27 +311,27 @@ static void linker_setup_linux(const char ***args_ref, Linker linker_type) } else { - global_context_add_link("m"); + linking_add_link(&compiler.linking, "m"); } - if (active_target.debug_info == DEBUG_INFO_FULL) + if (compiler.build.debug_info == DEBUG_INFO_FULL) { add_arg("-rdynamic"); } add_arg("-pthread"); return; } - if (active_target.debug_info == DEBUG_INFO_FULL) + if (compiler.build.debug_info == DEBUG_INFO_FULL) { add_arg("-export-dynamic"); } - if (is_no_pie(platform_target.reloc_model)) add_arg("-no-pie"); - if (is_pie(platform_target.reloc_model)) add_arg("-pie"); - if (platform_target.arch == ARCH_TYPE_X86_64) add_arg("--eh-frame-hdr"); + if (is_no_pie(compiler.platform.reloc_model)) add_arg("-no-pie"); + if (is_pie(compiler.platform.reloc_model)) add_arg("-pie"); + if (compiler.platform.arch == ARCH_TYPE_X86_64) add_arg("--eh-frame-hdr"); if (!link_libc()) return; const char *crt_begin_dir = find_linux_crt_begin(); const char *crt_dir = find_linux_crt(); - if (strip_unused() && active_target.type == TARGET_TYPE_EXECUTABLE) + if (strip_unused() && compiler.build.type == TARGET_TYPE_EXECUTABLE) { add_arg("--gc-sections"); } @@ -351,7 +340,7 @@ static void linker_setup_linux(const char ***args_ref, Linker linker_type) { error_exit("Failed to find the C runtime at link time."); } - if (is_pie_pic(platform_target.reloc_model)) + if (is_pie_pic(compiler.platform.reloc_model)) { add_arg("-pie"); add_arg2(crt_dir, "Scrt1.o"); @@ -371,21 +360,21 @@ static void linker_setup_linux(const char ***args_ref, Linker linker_type) add_arg("-L"); add_arg("/usr/lib/x86_64-linux-gnu/libdl.so"); add_arg("--dynamic-linker=/lib64/ld-linux-x86-64.so.2"); - global_context_add_link("m"); - global_context_add_link("pthread"); - global_context_add_link("c"); + linking_add_link(&compiler.linking, "m"); + linking_add_link(&compiler.linking, "pthread"); + linking_add_link(&compiler.linking, "c"); add_arg("-L/usr/lib/"); add_arg("-L/lib/"); add_arg("-m"); - add_arg(ld_target(platform_target.arch)); + add_arg(ld_target(compiler.platform.arch)); } static void linker_setup_freebsd(const char ***args_ref, Linker linker_type) { if (linker_type == LINKER_CC) return; - if (is_no_pie(platform_target.reloc_model)) add_arg("-no-pie"); - if (is_pie(platform_target.reloc_model)) add_arg("-pie"); - if (platform_target.arch == ARCH_TYPE_X86_64) add_arg("--eh-frame-hdr"); + if (is_no_pie(compiler.platform.reloc_model)) add_arg("-no-pie"); + if (is_pie(compiler.platform.reloc_model)) add_arg("-pie"); + if (compiler.platform.arch == ARCH_TYPE_X86_64) add_arg("--eh-frame-hdr"); if (!link_libc()) return; @@ -394,12 +383,12 @@ static void linker_setup_freebsd(const char ***args_ref, Linker linker_type) { error_exit("Failed to find the C runtime at link time."); } - if (strip_unused() && active_target.type == TARGET_TYPE_EXECUTABLE) + if (strip_unused() && compiler.build.type == TARGET_TYPE_EXECUTABLE) { add_arg("--gc-sections"); } - if (is_pie_pic(platform_target.reloc_model)) + if (is_pie_pic(compiler.platform.reloc_model)) { add_arg("-pie"); add_arg2(crt_dir, "Scrt1.o"); @@ -417,14 +406,14 @@ static void linker_setup_freebsd(const char ***args_ref, Linker linker_type) add_arg2(crt_dir, "crtn.o"); add_arg2("-L", crt_dir); add_arg("--dynamic-linker=/libexec/ld-elf.so.1"); - global_context_add_link("c"); - global_context_add_link("m"); - global_context_add_link("gcc"); - global_context_add_link("gcc_s"); + linking_add_link(&compiler.linking, "c"); + linking_add_link(&compiler.linking, "m"); + linking_add_link(&compiler.linking, "gcc"); + linking_add_link(&compiler.linking, "gcc_s"); add_arg("-L/usr/lib/"); add_arg("-m"); - add_arg(ld_target(platform_target.arch)); + add_arg(ld_target(compiler.platform.arch)); } static void add_linked_libs(const char ***args_ref, const char **libs, bool is_win) @@ -466,9 +455,9 @@ static void add_linked_libs(const char ***args_ref, const char **libs, bool is_w } static bool linker_setup(const char ***args_ref, const char **files_to_link, unsigned file_count, - const char *output_file, Linker linker_type) + const char *output_file, Linker linker_type, Linking *linking) { - bool is_dylib = active_target.type == TARGET_TYPE_DYNAMIC_LIB; + bool is_dylib = compiler.build.type == TARGET_TYPE_DYNAMIC_LIB; bool use_win = linker_type == LINKER_LINK_EXE; if (!use_win) { @@ -480,7 +469,7 @@ static bool linker_setup(const char ***args_ref, const char **files_to_link, uns case LINKER_UNKNOWN: break; case LINKER_WASM: - if (!is_dylib && active_target.no_entry) add_arg("--no-entry"); + if (!is_dylib && compiler.build.no_entry) add_arg("--no-entry"); break; case LINKER_LD64: if (is_dylib) vec_add(*args_ref, "-dylib"); @@ -496,7 +485,7 @@ static bool linker_setup(const char ***args_ref, const char **files_to_link, uns } else { - if (active_target.no_entry) add_arg("/NOENTRY"); + if (compiler.build.no_entry) add_arg("/NOENTRY"); } case LINKER_CC: break; @@ -505,7 +494,7 @@ static bool linker_setup(const char ***args_ref, const char **files_to_link, uns } const char *lib_path_opt = use_win ? "/LIBPATH:" : "-L"; - switch (platform_target.os) + switch (compiler.platform.os) { case OS_UNSUPPORTED: UNREACHABLE @@ -542,22 +531,22 @@ static bool linker_setup(const char ***args_ref, const char **files_to_link, uns add_arg(files_to_link[i]); } - FOREACH(const char *, dir, active_target.linker_libdirs) + FOREACH(const char *, dir, compiler.build.linker_libdirs) { add_arg2(lib_path_opt, dir); } - FOREACH(const char *, arg, active_target.link_args) + FOREACH(const char *, arg, compiler.build.link_args) { add_arg(arg); } - add_linked_libs(args_ref, active_target.linker_libs, use_win); - FOREACH(Library *, library, active_target.library_list) + add_linked_libs(args_ref, compiler.build.linker_libs, use_win); + FOREACH(Library *, library, compiler.build.library_list) { LibraryTarget *target = library->target_used; FOREACH(const char *, flag, target->link_flags) add_arg(flag); add_linked_libs(args_ref, target->linked_libs, use_win); } - add_linked_libs(args_ref, global_context.links, use_win); + add_linked_libs(args_ref, linking->links, use_win); return true; } #undef add_arg2 @@ -594,8 +583,8 @@ static void append_fpie_pic_options(RelocModel reloc, const char ***args_ref) Linker linker_find_linker_type(void) { - if (arch_is_wasm(platform_target.arch)) return LINKER_WASM; - switch (platform_target.os) + if (arch_is_wasm(compiler.platform.arch)) return LINKER_WASM; + switch (compiler.platform.os) { case OS_UNSUPPORTED: case OS_TYPE_UNKNOWN: @@ -623,7 +612,7 @@ static bool link_exe(const char *output_file, const char **files_to_link, unsign INFO_LOG("Using linker directly."); const char **args = NULL; Linker linker_type = linker_find_linker_type(); - linker_setup(&args, files_to_link, file_count, output_file, linker_type); + linker_setup(&args, files_to_link, file_count, output_file, linker_type, &compiler.linking); const char *error = NULL; // This isn't used in most cases, but its contents should get freed after linking. @@ -635,10 +624,10 @@ static bool link_exe(const char *output_file, const char **files_to_link, unsign arg_list = str_cat(arg_list, " "); arg_list = str_cat(arg_list, arg); } - INFO_LOG("Linker arguments: %s to %d", arg_list, platform_target.object_format); - if (active_target.print_linking) puts(arg_list); + INFO_LOG("Linker arguments: %s to %d", arg_list, compiler.platform.object_format); + if (compiler.build.print_linking) puts(arg_list); - switch (platform_target.object_format) + switch (compiler.platform.object_format) { case OBJ_FORMAT_COFF: success = llvm_link_coff(args, (int)vec_size(args), &error); @@ -707,11 +696,11 @@ void platform_linker(const char *output_file, const char **files, unsigned file_ { const char **parts = NULL; Linker linker_type = LINKER_CC; - if (active_target.linker_type == LINKER_TYPE_CUSTOM) + if (compiler.build.linker_type == LINKER_TYPE_CUSTOM) { - INFO_LOG("Using linker %s.", active_target.custom_linker_path); - vec_add(parts, active_target.custom_linker_path); - switch (platform_target.object_format) + INFO_LOG("Using linker %s.", compiler.build.custom_linker_path); + vec_add(parts, compiler.build.custom_linker_path); + switch (compiler.platform.object_format) { case OBJ_FORMAT_UNSUPPORTED: case OBJ_FORMAT_GOFF: @@ -736,23 +725,23 @@ void platform_linker(const char *output_file, const char **files, unsigned file_ else { INFO_LOG("Using cc linker."); - vec_add(parts, active_target.cc ? active_target.cc : "cc"); - append_fpie_pic_options(platform_target.reloc_model, &parts); + vec_add(parts, compiler.build.cc ? compiler.build.cc : "cc"); + append_fpie_pic_options(compiler.platform.reloc_model, &parts); } - linker_setup(&parts, files, file_count, output_file, linker_type); + linker_setup(&parts, files, file_count, output_file, linker_type, &compiler.linking); const char *output = concat_string_parts(parts); - if (active_target.print_linking) puts(output); + if (compiler.build.print_linking) puts(output); if (system(output) != 0) { error_exit("Failed to link executable '%s' using command '%s'.\n", output_file, output); } - if (os_is_apple(platform_target.os) && active_target.debug_info == DEBUG_INFO_FULL) + if (os_is_apple(compiler.platform.os) && compiler.build.debug_info == DEBUG_INFO_FULL) { // Create .dSYM scratch_buffer_clear(); - scratch_buffer_printf("dsymutil -arch %s %s", arch_to_linker_arch(platform_target.arch), output_file); - if (active_target.print_linking) puts(scratch_buffer_to_string()); + scratch_buffer_printf("dsymutil -arch %s %s", arch_to_linker_arch(compiler.platform.arch), output_file); + if (compiler.build.print_linking) puts(scratch_buffer_to_string()); if (system(scratch_buffer_to_string()) != 0) { puts("Failed to create .dSYM files, debugging will be impacted."); @@ -763,8 +752,8 @@ void platform_linker(const char *output_file, const char **files, unsigned file_ const char *cc_compiler(const char *cc, const char *file, const char *flags, const char **include_dirs, const char *output_subdir) { - const char *dir = active_target.object_file_dir; - if (!dir) dir = active_target.build_dir; + const char *dir = compiler.build.object_file_dir; + if (!dir) dir = compiler.build.build_dir; if (output_subdir) dir = file_append_path(dir, output_subdir); dir_make(dir); bool is_cl_exe = str_eq(cc, "cl.exe"); @@ -802,7 +791,7 @@ const char *cc_compiler(const char *cc, const char *file, const char *flags, con strstr(flags, "-fPIE")); // strcasestr is apparently nonstandard >:( if (!pie_set && !is_cl_exe) { - append_fpie_pic_options(platform_target.reloc_model, &parts); + append_fpie_pic_options(compiler.platform.reloc_model, &parts); } vec_add(parts, is_cl_exe ? "/c" : "-c"); @@ -831,14 +820,14 @@ bool dynamic_lib_linker(const char *output_file, const char **files, unsigned fi { INFO_LOG("Using linker directly."); const char **args = NULL; - if (active_target.linker_type == LINKER_TYPE_CUSTOM) vec_add(args, active_target.custom_linker_path); + if (compiler.build.linker_type == LINKER_TYPE_CUSTOM) vec_add(args, compiler.build.custom_linker_path); Linker linker_type = linker_find_linker_type(); - linker_setup(&args, files, file_count, output_file, linker_type); + linker_setup(&args, files, file_count, output_file, linker_type, &compiler.linking); const char *command = concat_string_parts(args); - if (active_target.print_linking) puts(command); - DEBUG_LOG("Linker arguments: %s to %d", command, platform_target.object_format); - if (active_target.linker_type == LINKER_TYPE_CUSTOM) + if (compiler.build.print_linking) puts(command); + DEBUG_LOG("Linker arguments: %s to %d", command, compiler.platform.object_format); + if (compiler.build.linker_type == LINKER_TYPE_CUSTOM) { if (system(command) != 0) { @@ -848,7 +837,7 @@ bool dynamic_lib_linker(const char *output_file, const char **files, unsigned fi } bool success; const char *error = NULL; - switch (platform_target.object_format) + switch (compiler.platform.object_format) { case OBJ_FORMAT_COFF: success = llvm_link_coff(args, (int)vec_size(args), &error); @@ -876,7 +865,7 @@ bool dynamic_lib_linker(const char *output_file, const char **files, unsigned fi bool static_lib_linker(const char *output_file, const char **files, unsigned file_count) { ArFormat format; - switch (platform_target.os) + switch (compiler.platform.os) { case OS_DARWIN_TYPES: format = AR_DARWIN; diff --git a/src/compiler/llvm_codegen.c b/src/compiler/llvm_codegen.c index 5381891d9..1c8f3d3e2 100644 --- a/src/compiler/llvm_codegen.c +++ b/src/compiler/llvm_codegen.c @@ -66,7 +66,7 @@ static void gencontext_init(GenContext *context, Module *module, LLVMContextRef { LLVMContextSetDiagnosticHandler(context->context, &diagnostics_handler, context); } - if (!active_target.emit_llvm && !active_target.test_output && !active_target.benchmark_output ) LLVMContextSetDiscardValueNames(context->context, true); + if (!compiler.build.emit_llvm && !compiler.build.test_output && !compiler.build.benchmark_output ) LLVMContextSetDiscardValueNames(context->context, true); context->code_module = module; } @@ -83,7 +83,7 @@ static void gencontext_destroy(GenContext *context) LLVMBuilderRef llvm_create_builder(GenContext *c) { LLVMBuilderRef builder = LLVMCreateBuilderInContext(c->context); - LLVMBuilderSetFastMathFlags(builder, (FastMathOption)active_target.feature.fp_math); + LLVMBuilderSetFastMathFlags(builder, (FastMathOption)compiler.build.feature.fp_math); return builder; } @@ -166,7 +166,7 @@ static LLVMValueRef llvm_emit_macho_xtor(GenContext *c, LLVMValueRef *list, cons void llvm_emit_constructors_and_destructors(GenContext *c) { - if (platform_target.object_format == OBJ_FORMAT_MACHO) + if (compiler.platform.object_format == OBJ_FORMAT_MACHO) { LLVMValueRef c3_dynamic = LLVMGetNamedGlobal(c->module, "$c3_dynamic"); @@ -616,8 +616,8 @@ static void gencontext_verify_ir(GenContext *context) static void gencontext_emit_object_file(GenContext *context) { char *err = ""; - DEBUG_LOG("Target: %s", platform_target.target_triple); - LLVMSetTarget(context->module, platform_target.target_triple); + DEBUG_LOG("Target: %s", compiler.platform.target_triple); + LLVMSetTarget(context->module, compiler.platform.target_triple); char *layout = LLVMCopyStringRepOfTargetData(context->target_data); LLVMSetDataLayout(context->module, layout); LLVMDisposeMessage(layout); @@ -642,8 +642,8 @@ static void gencontext_emit_object_file(GenContext *context) static void llvm_emit_asm_file(GenContext *context) { char *err = ""; - DEBUG_LOG("Target: %s", platform_target.target_triple); - LLVMSetTarget(context->module, platform_target.target_triple); + DEBUG_LOG("Target: %s", compiler.platform.target_triple); + LLVMSetTarget(context->module, compiler.platform.target_triple); char *layout = LLVMCopyStringRepOfTargetData(context->target_data); LLVMSetDataLayout(context->module, layout); LLVMDisposeMessage(layout); @@ -852,7 +852,7 @@ static void llvm_codegen_setup() void llvm_set_comdat(GenContext *c, LLVMValueRef global) { - if (!platform_target.use_comdat) return; + if (!compiler.platform.use_comdat) return; LLVMComdatRef comdat = LLVMGetOrInsertComdat(c->module, LLVMGetValueName(global)); LLVMSetComdatSelectionKind(comdat, LLVMAnyComdatSelectionKind); LLVMSetComdat(global, comdat); @@ -952,7 +952,7 @@ static inline void llvm_optimize(GenContext *c) #endif LLVMOptLevels level = LLVM_O0; - switch (active_target.optsize) + switch (compiler.build.optsize) { case SIZE_OPTIMIZATION_SMALL: level = LLVM_Os; @@ -961,7 +961,7 @@ static inline void llvm_optimize(GenContext *c) level = LLVM_Oz; break; default: - switch (active_target.optlevel) + switch (compiler.build.optlevel) { case OPTIMIZATION_NONE: case OPTIMIZATION_NOT_SET: @@ -981,14 +981,14 @@ static inline void llvm_optimize(GenContext *c) } LLVMPasses passes = { .opt_level = level, - .should_verify = active_target.emit_llvm, + .should_verify = compiler.build.emit_llvm, .should_debug = should_debug, - .is_kernel = active_target.kernel_build, - .opt.vectorize_loops = active_target.loop_vectorization == VECTORIZATION_ON, - .opt.slp_vectorize = active_target.slp_vectorization == VECTORIZATION_ON, - .opt.unroll_loops = active_target.unroll_loops == UNROLL_LOOPS_ON, - .opt.interleave_loops = active_target.unroll_loops == UNROLL_LOOPS_ON, - .opt.merge_functions = active_target.merge_functions == MERGE_FUNCTIONS_ON + .is_kernel = compiler.build.kernel_build, + .opt.vectorize_loops = compiler.build.loop_vectorization == VECTORIZATION_ON, + .opt.slp_vectorize = compiler.build.slp_vectorization == VECTORIZATION_ON, + .opt.unroll_loops = compiler.build.unroll_loops == UNROLL_LOOPS_ON, + .opt.interleave_loops = compiler.build.unroll_loops == UNROLL_LOOPS_ON, + .opt.merge_functions = compiler.build.merge_functions == MERGE_FUNCTIONS_ON }; if (!llvm_run_passes(c->module, c->machine, &passes)) { @@ -1002,20 +1002,20 @@ const char *llvm_codegen(void *context) llvm_optimize(c); // Serialize the LLVM IR, if requested, also verify the IR in this case - if (active_target.emit_llvm) + if (compiler.build.emit_llvm) { gencontext_print_llvm_ir(c); gencontext_verify_ir(c); } const char *object_name = NULL; - if (active_target.emit_object_files) + if (compiler.build.emit_object_files) { gencontext_emit_object_file(c); object_name = c->object_filename; } - if (active_target.emit_asm) + if (compiler.build.emit_asm) { llvm_emit_asm_file(context); } @@ -1163,7 +1163,7 @@ void llvm_append_function_attributes(GenContext *c, Decl *decl) { llvm_attribute_add(c, function, attribute_id.noreturn, -1); } - if (decl->is_export && arch_is_wasm(platform_target.arch)) + if (decl->is_export && arch_is_wasm(compiler.platform.arch)) { if (c->code_module == decl->unit->module) { @@ -1171,7 +1171,7 @@ void llvm_append_function_attributes(GenContext *c, Decl *decl) llvm_attribute_add_string(c, function, "wasm-export-name", scratch_buffer_to_string(), -1); } } - if (decl->is_extern && arch_is_wasm(platform_target.arch)) + if (decl->is_extern && arch_is_wasm(compiler.platform.arch)) { scratch_buffer_set_extern_decl_name(decl, true); llvm_attribute_add_string(c, function, "wasm-import-name", scratch_buffer_to_string(), -1); @@ -1209,7 +1209,7 @@ LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl) } assert(decl->var.kind == VARDECL_GLOBAL || decl->var.kind == VARDECL_CONST); llvm_add_global_decl(c, decl); - if (decl->is_export && platform_target.os == OS_TYPE_WIN32 && !active_target.win.def) + if (decl->is_export && compiler.platform.os == OS_TYPE_WIN32 && !compiler.build.win.def) { LLVMSetDLLStorageClass(decl->backend_ref, LLVMDLLExportStorageClass); } @@ -1230,7 +1230,7 @@ LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl) backend_ref = decl->backend_ref = LLVMAddFunction(c->module, scratch_buffer_to_string(), type); } llvm_append_function_attributes(c, decl); - if (decl->is_export && platform_target.os == OS_TYPE_WIN32 && !active_target.win.def && decl->name != kw_main && decl->name != kw_mainstub) + if (decl->is_export && compiler.platform.os == OS_TYPE_WIN32 && !compiler.build.win.def && decl->name != kw_main && decl->name != kw_mainstub) { LLVMSetDLLStorageClass(backend_ref, LLVMDLLExportStorageClass); } @@ -1277,13 +1277,13 @@ LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl) static void llvm_gen_test_main(GenContext *c) { - Decl *test_runner = global_context.test_func; + Decl *test_runner = compiler.context.test_func; if (!test_runner) { error_exit("No test runner found."); } - assert(!global_context.main && "Main should not be set if a test main is generated."); - global_context.main = test_runner; + assert(!compiler.context.main && "Main should not be set if a test main is generated."); + compiler.context.main = test_runner; LLVMTypeRef cint = llvm_get_type(c, type_cint); LLVMTypeRef main_type = LLVMFunctionType(cint, NULL, 0, true); LLVMTypeRef runner_type = LLVMFunctionType(c->byte_type, NULL, 0, true); @@ -1304,7 +1304,7 @@ INLINE GenContext *llvm_gen_tests(Module** modules, unsigned module_count, LLVMC Module *test_module = compiler_find_or_create_module(test_path, NULL); GenContext *c = cmalloc(sizeof(GenContext)); - active_target.debug_info = DEBUG_INFO_NONE; + compiler.build.debug_info = DEBUG_INFO_NONE; gencontext_init(c, test_module, shared_context); gencontext_begin_module(c); @@ -1361,7 +1361,7 @@ INLINE GenContext *llvm_gen_tests(Module** modules, unsigned module_count, LLVMC LLVMSetGlobalConstant(decl_list, 1); LLVMSetInitializer(decl_list, llvm_emit_aggregate_two(c, decls_array_type, decl_ref, count)); - if (active_target.type == TARGET_TYPE_TEST) + if (compiler.build.type == TARGET_TYPE_TEST) { llvm_gen_test_main(c); } @@ -1376,13 +1376,13 @@ INLINE GenContext *llvm_gen_tests(Module** modules, unsigned module_count, LLVMC static void llvm_gen_benchmark_main(GenContext *c) { - Decl *benchmark_runner = global_context.benchmark_func; + Decl *benchmark_runner = compiler.context.benchmark_func; if (!benchmark_runner) { error_exit("No benchmark runner found."); } - assert(!global_context.main && "Main should not be set if a benchmark main is generated."); - global_context.main = benchmark_runner; + assert(!compiler.context.main && "Main should not be set if a benchmark main is generated."); + compiler.context.main = benchmark_runner; LLVMTypeRef cint = llvm_get_type(c, type_cint); LLVMTypeRef main_type = LLVMFunctionType(cint, NULL, 0, true); LLVMTypeRef runner_type = LLVMFunctionType(c->byte_type, NULL, 0, true); @@ -1403,7 +1403,7 @@ INLINE GenContext *llvm_gen_benchmarks(Module** modules, unsigned module_count, Module *benchmark_module = compiler_find_or_create_module(benchmark_path, NULL); GenContext *c = cmalloc(sizeof(GenContext)); - active_target.debug_info = DEBUG_INFO_NONE; + compiler.build.debug_info = DEBUG_INFO_NONE; gencontext_init(c, benchmark_module, shared_context); gencontext_begin_module(c); @@ -1460,7 +1460,7 @@ INLINE GenContext *llvm_gen_benchmarks(Module** modules, unsigned module_count, LLVMSetGlobalConstant(decl_list, 1); LLVMSetInitializer(decl_list, llvm_emit_aggregate_two(c, decls_array_type, decl_ref, count)); - if (active_target.type == TARGET_TYPE_BENCHMARK) + if (compiler.build.type == TARGET_TYPE_BENCHMARK) { llvm_gen_benchmark_main(c); } @@ -1478,7 +1478,7 @@ void **llvm_gen(Module** modules, unsigned module_count) if (!module_count) return NULL; GenContext **gen_contexts = NULL; llvm_codegen_setup(); - if (active_target.single_module == SINGLE_MODULE_ON) + if (compiler.build.single_module == SINGLE_MODULE_ON) { GenContext *first_context; unsigned first_element; @@ -1491,11 +1491,11 @@ void **llvm_gen(Module** modules, unsigned module_count) } if (!gen_contexts) return NULL; GenContext *first = gen_contexts[0]; - if (active_target.benchmarking) + if (compiler.build.benchmarking) { vec_add(gen_contexts, llvm_gen_benchmarks(modules, module_count, context)); } - if (active_target.testing) + if (compiler.build.testing) { vec_add(gen_contexts, llvm_gen_tests(modules, module_count, context)); } @@ -1515,11 +1515,11 @@ void **llvm_gen(Module** modules, unsigned module_count) if (!result) continue; vec_add(gen_contexts, result); } - if (active_target.benchmarking) + if (compiler.build.benchmarking) { vec_add(gen_contexts, llvm_gen_benchmarks(modules, module_count, NULL)); } - if (active_target.testing) + if (compiler.build.testing) { vec_add(gen_contexts, llvm_gen_tests(modules, module_count, NULL)); } @@ -1556,7 +1556,7 @@ static bool module_is_stdlib(Module *module) static GenContext *llvm_gen_module(Module *module, LLVMContextRef shared_context) { if (!vec_size(module->units)) return NULL; - if (active_target.emit_stdlib == EMIT_STDLIB_OFF && module_is_stdlib(module)) return NULL; + if (compiler.build.emit_stdlib == EMIT_STDLIB_OFF && module_is_stdlib(module)) return NULL; assert(intrinsics_setup); @@ -1596,12 +1596,12 @@ static GenContext *llvm_gen_module(Module *module, LLVMContextRef shared_context if (only_used && !func->is_live) continue; if (func->func_decl.attr_test) { - if (!active_target.testing) continue; + if (!compiler.build.testing) continue; vec_add(module->tests, func); } if (func->func_decl.attr_benchmark) { - if (!active_target.benchmarking) continue; + if (!compiler.build.benchmarking) continue; vec_add(module->benchmarks, func); } llvm_emit_function_decl(gen_context, func); @@ -1615,7 +1615,7 @@ static GenContext *llvm_gen_module(Module *module, LLVMContextRef shared_context llvm_emit_function_decl(gen_context, func); } - if (active_target.type != TARGET_TYPE_TEST && active_target.type != TARGET_TYPE_BENCHMARK && unit->main_function && unit->main_function->is_synthetic) + if (compiler.build.type != TARGET_TYPE_TEST && compiler.build.type != TARGET_TYPE_BENCHMARK && unit->main_function && unit->main_function->is_synthetic) { has_elements = true; llvm_emit_function_decl(gen_context, unit->main_function); @@ -1646,8 +1646,8 @@ static GenContext *llvm_gen_module(Module *module, LLVMContextRef shared_context FOREACH(Decl *, decl, unit->functions) { - if (decl->func_decl.attr_test && !active_target.testing) continue; - if (decl->func_decl.attr_benchmark && !active_target.benchmarking) continue; + if (decl->func_decl.attr_test && !compiler.build.testing) continue; + if (decl->func_decl.attr_benchmark && !compiler.build.benchmarking) continue; if (only_used && !decl->is_live) continue; if (decl->func_decl.body) { @@ -1663,7 +1663,7 @@ static GenContext *llvm_gen_module(Module *module, LLVMContextRef shared_context llvm_emit_function_body(gen_context, func); } - if (active_target.type != TARGET_TYPE_TEST && active_target.type != TARGET_TYPE_BENCHMARK && unit->main_function && unit->main_function->is_synthetic) + if (compiler.build.type != TARGET_TYPE_TEST && compiler.build.type != TARGET_TYPE_BENCHMARK && unit->main_function && unit->main_function->is_synthetic) { has_elements = true; llvm_emit_function_body(gen_context, unit->main_function); @@ -1692,7 +1692,7 @@ static GenContext *llvm_gen_module(Module *module, LLVMContextRef shared_context } // If it's in test or benchmark, then we want to serialize the IR before it is optimized. - if (active_target.test_output || active_target.benchmark_output) + if (compiler.build.test_output || compiler.build.benchmark_output) { gencontext_print_llvm_ir(gen_context); gencontext_verify_ir(gen_context); diff --git a/src/compiler/llvm_codegen_builtins.c b/src/compiler/llvm_codegen_builtins.c index 5e6975d48..74ce48ab2 100644 --- a/src/compiler/llvm_codegen_builtins.c +++ b/src/compiler/llvm_codegen_builtins.c @@ -285,13 +285,13 @@ static inline void llvm_emit_syscall(GenContext *c, BEValue *be_value, Expr *exp LLVMTypeRef func_type = LLVMFunctionType(type, arg_types, arguments, false); scratch_buffer_clear(); LLVMValueRef inline_asm; - switch (platform_target.arch) + switch (compiler.platform.arch) { case ARCH_TYPE_AARCH64: case ARCH_TYPE_AARCH64_BE: scratch_buffer_append("={x0}"); assert(arguments < 8); - if (os_is_apple(platform_target.os)) + if (os_is_apple(compiler.platform.os)) { static char const *regs[] = { "x16", "x0", "x1", "x2", "x3", "x4", "x5" }; llvm_syscall_write_regs_to_scratch(regs, arguments); @@ -961,7 +961,7 @@ void llvm_emit_builtin_call(GenContext *c, BEValue *result_value, Expr *expr) llvm_emit_masked_load(c, result_value, expr); return; case BUILTIN_EXPECT_WITH_PROBABILITY: - if (active_target.optlevel == OPTIMIZATION_NONE) + if (compiler.build.optlevel == OPTIMIZATION_NONE) { Expr **args = expr->call_expr.arguments; llvm_emit_expr(c, result_value, args[0]); @@ -1068,7 +1068,7 @@ void llvm_emit_builtin_call(GenContext *c, BEValue *result_value, Expr *expr) return; case BUILTIN_WASM_MEMORY_GROW: // -1 on non-wasm - if (!arch_is_wasm(platform_target.arch)) + if (!arch_is_wasm(compiler.platform.arch)) { llvm_value_set(result_value, llvm_const_int(c, expr->type, -1), expr->type); return; @@ -1076,7 +1076,7 @@ void llvm_emit_builtin_call(GenContext *c, BEValue *result_value, Expr *expr) llvm_emit_builtin_args_types3(c, result_value, expr, intrinsic_id.wasm_memory_grow, expr->type, NULL, NULL); return; case BUILTIN_WASM_MEMORY_SIZE: - if (!arch_is_wasm(platform_target.arch)) + if (!arch_is_wasm(compiler.platform.arch)) { // 0 (no mem) on non-wasm. llvm_value_set(result_value, llvm_const_int(c, expr->type, 0), expr->type); diff --git a/src/compiler/llvm_codegen_debug_info.c b/src/compiler/llvm_codegen_debug_info.c index 5379f69c8..2b2a18da2 100644 --- a/src/compiler/llvm_codegen_debug_info.c +++ b/src/compiler/llvm_codegen_debug_info.c @@ -104,7 +104,7 @@ void llvm_emit_debug_function(GenContext *c, Decl *decl) true, row, flags, - active_target.optlevel != OPTIMIZATION_NONE); + compiler.build.optlevel != OPTIMIZATION_NONE); LLVMSetSubprogram(decl->backend_ref, c->debug.function); } @@ -161,7 +161,7 @@ void llvm_emit_debug_local_var(GenContext *c, Decl *decl) c->debug.file.debug_file, row, llvm_get_debug_type(c, decl->type), - active_target.optlevel != OPTIMIZATION_NONE, + compiler.build.optlevel != OPTIMIZATION_NONE, LLVMDIFlagZero, decl->alignment); decl->var.backend_debug_ref = var; @@ -482,7 +482,7 @@ static LLVMMetadataRef llvm_debug_typedef_type(GenContext *c, Type *type) Decl *decl = type->decl; // Is this a primitive typedef? If so, we create it without reference. - if (decl->unit == global_context.core_unit) + if (decl->unit == compiler.context.core_unit) { return LLVMDIBuilderCreateTypedef(c->debug.builder, llvm_get_debug_type(c, type_lowering(type)), diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index bb67d183b..5629849e0 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -329,7 +329,7 @@ LLVMValueRef llvm_emit_const_padding(GenContext *c, AlignSize size) static inline LLVMValueRef llvm_emit_add_int(GenContext *c, Type *type, LLVMValueRef left, LLVMValueRef right, SourceSpan loc) { - if (active_target.feature.trap_on_wrap) + if (compiler.build.feature.trap_on_wrap) { LLVMTypeRef type_to_use = llvm_get_type(c, type->canonical); LLVMValueRef args[2] = { left, right }; @@ -418,7 +418,7 @@ LLVMValueRef llvm_coerce_int_ptr(GenContext *c, LLVMValueRef value, LLVMTypeRef // 4. Are int types not matching? if (to_int_type != from) { - if (platform_target.big_endian) + if (compiler.platform.big_endian) { // Big endian, preserve the high bits. ByteSize to_size = llvm_abi_size(c, to_int_type); @@ -565,7 +565,7 @@ void llvm_emit_convert_value_from_coerced(GenContext *c, BEValue *result, LLVMTy static inline LLVMValueRef llvm_emit_sub_int(GenContext *c, Type *type, LLVMValueRef left, LLVMValueRef right, SourceSpan loc) { - if (active_target.feature.trap_on_wrap) + if (compiler.build.feature.trap_on_wrap) { LLVMTypeRef type_to_use = llvm_get_type(c, type); LLVMValueRef args[2] = { left, right }; @@ -2155,7 +2155,7 @@ static inline void llvm_emit_initialize_reference_designated(GenContext *c, BEVa static bool bitstruct_requires_bitswap(Decl *decl) { assert(decl->decl_kind == DECL_BITSTRUCT); - bool big_endian = platform_target.big_endian; + bool big_endian = compiler.platform.big_endian; if (decl->bitstruct.big_endian) return !big_endian; if (decl->bitstruct.little_endian) return big_endian; return false; @@ -2710,7 +2710,7 @@ static void llvm_emit_unary_expr(GenContext *c, BEValue *value, Expr *expr) return; } assert(type->canonical != type_bool); - if (active_target.feature.trap_on_wrap && !type_flat_is_vector(value->type)) + if (compiler.build.feature.trap_on_wrap && !type_flat_is_vector(value->type)) { LLVMValueRef zero = llvm_get_zero(c, expr->unary_expr.expr->type); LLVMTypeRef type_to_use = llvm_get_type(c, type->canonical); @@ -3570,7 +3570,7 @@ static void llvm_emit_struct_comparison(GenContext *c, BEValue *result, BEValue static inline LLVMValueRef llvm_emit_mult_int(GenContext *c, Type *type, LLVMValueRef left, LLVMValueRef right, SourceSpan loc) { - if (active_target.feature.trap_on_wrap) + if (compiler.build.feature.trap_on_wrap) { LLVMTypeRef type_to_use = llvm_get_type(c, type); LLVMValueRef args[2] = { left, right }; @@ -4068,7 +4068,8 @@ static void llvm_emit_else(GenContext *c, BEValue *be_value, Expr *expr) llvm_new_phi(c, be_value, "val", expr->type, real_value.value, success_end_block, else_value.value, else_block_exit); } -typedef enum { +typedef enum +{ FMUL_NONE, FMUL_LHS_MULT, FMUL_LHS_NEG_MULT, @@ -4078,7 +4079,7 @@ typedef enum { INLINE FmulTransformation llvm_get_fmul_transformation(Expr *lhs, Expr *rhs) { - if (active_target.feature.fp_math <= FP_STRICT) return FMUL_NONE; + if (compiler.build.feature.fp_math <= FP_STRICT) return FMUL_NONE; // x * y + z if (expr_is_mult(lhs)) return FMUL_LHS_MULT; // -(x * y) + z diff --git a/src/compiler/llvm_codegen_function.c b/src/compiler/llvm_codegen_function.c index a2d912b37..3365c79b3 100644 --- a/src/compiler/llvm_codegen_function.c +++ b/src/compiler/llvm_codegen_function.c @@ -544,7 +544,7 @@ void llvm_emit_dynamic_functions(GenContext *c, Decl **funcs) { size_t len = vec_size(funcs); if (!len) return; - if (platform_target.object_format == OBJ_FORMAT_MACHO) + if (compiler.platform.object_format == OBJ_FORMAT_MACHO) { LLVMTypeRef types[3] = { c->ptr_type, c->ptr_type, c->typeid_type }; LLVMTypeRef entry_type = LLVMStructType(types, 3, false); diff --git a/src/compiler/llvm_codegen_internal.h b/src/compiler/llvm_codegen_internal.h index 3ec9c5e5f..206748a56 100644 --- a/src/compiler/llvm_codegen_internal.h +++ b/src/compiler/llvm_codegen_internal.h @@ -18,6 +18,7 @@ extern const char *varargslots_name; extern const char *temp_name; + typedef enum { BE_VALUE, @@ -562,8 +563,7 @@ LLVMMetadataRef llvm_create_debug_location(GenContext *c, SourceSpan location); void llvm_emit_debug_parameter(GenContext *c, Decl *parameter, unsigned index); void llvm_emit_debug_local_var(GenContext *c, Decl *var); -#define FRAMEPOINTER (platform_target.arch == ARCH_TYPE_AARCH64 ? 1 : 2) -#define UWTABLE (active_target.arch_os_target == MACOS_AARCH64 ? 1 : 2) +#define UWTABLE (compiler.build.arch_os_target == MACOS_AARCH64 ? 1 : 2) #define EMIT_LOC(c, x) do { if (c->debug.builder) llvm_emit_debug_location(c, x->span); } while (0) #define EMIT_SPAN(c, x) do { if (c->debug.builder) llvm_emit_debug_location(c, x); } while (0) diff --git a/src/compiler/llvm_codegen_internal_impl.h b/src/compiler/llvm_codegen_internal_impl.h index af01eca33..4bcdb004b 100644 --- a/src/compiler/llvm_codegen_internal_impl.h +++ b/src/compiler/llvm_codegen_internal_impl.h @@ -163,7 +163,7 @@ INLINE LLVMValueRef llvm_emit_extract_value(GenContext *c, LLVMValueRef agg, uns INLINE bool llvm_use_accurate_debug_info(GenContext *context) { - return context->debug.builder && active_target.optlevel <= OPTIMIZATION_NONE; + return context->debug.builder && compiler.build.optlevel <= OPTIMIZATION_NONE; } INLINE bool llvm_use_debug(GenContext *context) { return context->debug.builder != NULL; } diff --git a/src/compiler/llvm_codegen_module.c b/src/compiler/llvm_codegen_module.c index fe82b69c7..5f18cf130 100644 --- a/src/compiler/llvm_codegen_module.c +++ b/src/compiler/llvm_codegen_module.c @@ -61,8 +61,8 @@ void gencontext_begin_module(GenContext *c) codegen_setup_object_names(c->code_module, &c->ir_filename, &c->asm_filename, &c->object_filename); - c->panic_var = global_context.panic_var; - c->panicf = global_context.panicf; + c->panic_var = compiler.context.panic_var; + c->panicf = compiler.context.panicf; c->module = LLVMModuleCreateWithNameInContext(c->code_module->name->module, c->context); c->machine = llvm_target_machine_create(); @@ -73,7 +73,7 @@ void gencontext_begin_module(GenContext *c) static const char *pic_level = "PIC Level"; static const char *pie_level = "PIE Level"; - switch (active_target.reloc_model) + switch (compiler.build.reloc_model) { case RELOC_BIG_PIE: llvm_set_module_flag(c, LLVMModuleFlagBehaviorOverride, pie_level, (unsigned)2 /* PIE */, type_uint); @@ -91,14 +91,14 @@ void gencontext_begin_module(GenContext *c) break; } - LLVMSetTarget(c->module, platform_target.target_triple); + LLVMSetTarget(c->module, compiler.platform.target_triple); // Setup all types. Not thread-safe, but at this point in time we can assume a single context. // We need to remove the context from the cache after this. // This would seem to indicate that we should change Type / actual type. - c->ast_alloca_addr_space = target_alloca_addr_space(); - FOREACH(Type *, type, global_context.type) + c->ast_alloca_addr_space = compiler.platform.alloca_address_space; + FOREACH(Type *, type, compiler.context.type) { type->backend_type = NULL; type->backend_debug_type = NULL; @@ -145,25 +145,26 @@ void gencontext_begin_module(GenContext *c) if (c->panic_var) c->panic_var->backend_ref = NULL; if (c->panicf) c->panicf->backend_ref = NULL; - if (active_target.debug_info != DEBUG_INFO_NONE) + if (compiler.build.debug_info != DEBUG_INFO_NONE) { - if (active_target.arch_os_target == WINDOWS_X64 || active_target.arch_os_target == WINDOWS_AARCH64) + if (compiler.build.arch_os_target == WINDOWS_X64 || compiler.build.arch_os_target == WINDOWS_AARCH64) { llvm_set_module_flag(c, LLVMModuleFlagBehaviorError, "CodeView", 1, type_uint); } else { + unsigned frame_pointer = compiler.platform.arch == ARCH_TYPE_AARCH64 ? 1 : 2; llvm_set_module_flag(c, LLVMModuleFlagBehaviorWarning, "Dwarf Version", 4, type_uint); llvm_set_module_flag(c, LLVMModuleFlagBehaviorWarning, "Debug Info Version", 3, type_uint); - llvm_set_module_flag(c, LLVMModuleFlagBehaviorWarning, "frame-pointer", FRAMEPOINTER, type_uint); + llvm_set_module_flag(c, LLVMModuleFlagBehaviorWarning, "frame-pointer", frame_pointer, type_uint); } llvm_set_module_flag(c, LLVMModuleFlagBehaviorError, "uwtable", UWTABLE, type_uint); c->debug.runtime_version = 0; c->debug.builder = LLVMCreateDIBuilder(c->module); - if (active_target.debug_info == DEBUG_INFO_FULL && safe_mode_enabled()) + if (compiler.build.debug_info == DEBUG_INFO_FULL && safe_mode_enabled()) { - c->debug.enable_stacktrace = os_supports_stacktrace(platform_target.os); + c->debug.enable_stacktrace = os_supports_stacktrace(compiler.platform.os); } } c->global_builder = LLVMCreateBuilder(); @@ -172,16 +173,16 @@ void gencontext_begin_module(GenContext *c) void gencontext_init_file_emit(GenContext *c, CompilationUnit *unit) { - if (active_target.debug_info != DEBUG_INFO_NONE) + if (compiler.build.debug_info != DEBUG_INFO_NONE) { // Set runtime version here. unit->llvm.debug_file = llvm_get_debug_file(c, unit->file->file_id); - bool is_optimized = active_target.optlevel != OPTIMIZATION_NONE; + bool is_optimized = compiler.build.optlevel != OPTIMIZATION_NONE; const char *dwarf_flags = ""; unsigned runtime_version = 0; LLVMDWARFEmissionKind emission_kind = - active_target.debug_info == DEBUG_INFO_FULL ? LLVMDWARFEmissionFull : LLVMDWARFEmissionLineTablesOnly; + compiler.build.debug_info == DEBUG_INFO_FULL ? LLVMDWARFEmissionFull : LLVMDWARFEmissionLineTablesOnly; const char *debug_output_file = ""; bool emit_debug_info_for_profiling = false; bool split_debug_inlining = false; diff --git a/src/compiler/llvm_codegen_stmt.c b/src/compiler/llvm_codegen_stmt.c index 99ef0c455..735149698 100644 --- a/src/compiler/llvm_codegen_stmt.c +++ b/src/compiler/llvm_codegen_stmt.c @@ -1205,7 +1205,7 @@ static inline void llvm_emit_assert_stmt(GenContext *c, Ast *ast) static inline void add_target_clobbers_to_buffer(GenContext *c) { - switch (platform_target.arch) + switch (compiler.platform.arch) { case ARCH_TYPE_X86_64: case ARCH_TYPE_X86: @@ -1361,10 +1361,10 @@ static inline void llvm_emit_asm_block_stmt(GenContext *c, Ast *ast) mask <<= 1; } } - if (asm_target.extra_clobbers) + if (compiler.platform.extra_clobbers) { codegen_new_constraint(&clobber_list); - codegen_append_constraints(&clobber_list, asm_target.extra_clobbers); + codegen_append_constraints(&clobber_list, compiler.platform.extra_clobbers); } } DEBUG_LOG("Asm: %s (%s)", data, clobbers); diff --git a/src/compiler/module.c b/src/compiler/module.c index 290e37365..70a900e86 100644 --- a/src/compiler/module.c +++ b/src/compiler/module.c @@ -43,7 +43,7 @@ void scratch_buffer_append_module(Module *module, bool is_export) const char *module_create_object_file_name(Module *module) { - if (active_target.single_module == SINGLE_MODULE_ON && active_target.name) return active_target.name; + if (compiler.build.single_module == SINGLE_MODULE_ON && compiler.build.name) return compiler.build.name; scratch_buffer_clear(); char c; const char *name = module->name->module; diff --git a/src/compiler/parse_expr.c b/src/compiler/parse_expr.c index 350f70a86..d1089e616 100644 --- a/src/compiler/parse_expr.c +++ b/src/compiler/parse_expr.c @@ -1136,7 +1136,7 @@ static Expr *parse_ct_concat_append(ParseContext *c, Expr *left) { assert(!left && "Unexpected left hand side"); Expr *expr = EXPR_NEW_TOKEN(tok_is(c, TOKEN_CT_CONCATFN) ? EXPR_CT_CONCAT : EXPR_CT_APPEND); - if (!active_target.silence_deprecation) SEMA_NOTE(expr, "'%s' is deprecated in favour of '+++'.", symstr(c)); + if (!compiler.build.silence_deprecation) SEMA_NOTE(expr, "'%s' is deprecated in favour of '+++'.", symstr(c)); advance(c); CONSUME_OR_RET(TOKEN_LPAREN, poisoned_expr); @@ -1172,7 +1172,7 @@ static Expr *parse_ct_and_or(ParseContext *c, Expr *left) assert(!left && "Unexpected left hand side"); Expr *expr = EXPR_NEW_TOKEN(EXPR_CT_AND_OR); expr->ct_and_or_expr.is_and = tok_is(c, TOKEN_CT_ANDFN); - if (!active_target.silence_deprecation) SEMA_NOTE(expr, "The use of '%s' is deprecated in favour of '&&&'.", symstr(c)); + if (!compiler.build.silence_deprecation) SEMA_NOTE(expr, "The use of '%s' is deprecated in favour of '&&&'.", symstr(c)); advance(c); CONSUME_OR_RET(TOKEN_LPAREN, poisoned_expr); if (!parse_expr_list(c, &expr->ct_and_or_expr.args, TOKEN_RPAREN)) return poisoned_expr; diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index 9f09504fc..da31c2285 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -2460,7 +2460,7 @@ static inline bool parse_contract_param(ParseContext *c, AstId *docs, AstId **do // [inout] [in] [out] bool is_ref = false; - InOutModifier mod = PARAM_ANY; + InOutModifier mod = INOUT_ANY; if (try_consume(c, TOKEN_LBRACKET)) { is_ref = try_consume(c, TOKEN_AMP); @@ -2468,15 +2468,15 @@ static inline bool parse_contract_param(ParseContext *c, AstId *docs, AstId **do if (modifier) advance(c); if (modifier == kw_in) { - mod = PARAM_IN; + mod = INOUT_IN; } else if (modifier == kw_inout) { - mod = PARAM_INOUT; + mod = INOUT_INOUT; } else if (modifier == kw_out) { - mod = PARAM_OUT; + mod = INOUT_OUT; } else { diff --git a/src/compiler/parser.c b/src/compiler/parser.c index cf7fcdb6b..635c8c693 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -102,9 +102,9 @@ bool parse_file(File *file) ParseContext parse_context = { .unit = unit }; parse_context.lexer = (Lexer) { .file = file, .context = &parse_context }; lexer_init(&parse_context.lexer); - if (global_context.errors_found) return false; + if (compiler.context.errors_found) return false; parse_translation_unit(&parse_context); - return !global_context.errors_found; + return !compiler.context.errors_found; } Decl **parse_include_file(File *file, CompilationUnit *unit) @@ -175,7 +175,7 @@ bool parse_stdin(void) { stdin_file = (File){ .name = "stdin", - .file_id = stdin_file_id, + .file_id = STDIN_FILE_ID, .full_path = "", }; #define BUF_SIZE 65536 @@ -211,9 +211,9 @@ bool parse_stdin(void) ParseContext parse_context = { .unit = unit }; parse_context.lexer = (Lexer) { .file = &stdin_file, .context = &parse_context }; lexer_init(&parse_context.lexer); - if (global_context.errors_found) return false; + if (compiler.context.errors_found) return false; parse_translation_unit(&parse_context); - return !global_context.errors_found; + return !compiler.context.errors_found; } diff --git a/src/compiler/sema_asm.c b/src/compiler/sema_asm.c index c86f42f72..59423a33c 100644 --- a/src/compiler/sema_asm.c +++ b/src/compiler/sema_asm.c @@ -182,7 +182,7 @@ static inline bool sema_check_asm_arg_addr(SemaContext *context, AsmInlineBlock static inline bool sema_check_asm_arg_reg(SemaContext *context, AsmInlineBlock *block, AsmInstruction *instr, AsmArgType arg_type, Expr *expr) { const char *name = expr->expr_asm_arg.reg.name; - AsmRegister *reg = expr->expr_asm_arg.reg.ref = asm_reg_by_name(name); + AsmRegister *reg = expr->expr_asm_arg.reg.ref = asm_reg_by_name(&compiler.platform, name); if (!reg) { SEMA_ERROR(expr, "Expected a valid register name."); @@ -477,13 +477,13 @@ static inline bool sema_check_asm_arg(SemaContext *context, AsmInlineBlock *bloc } bool sema_analyse_asm(SemaContext *context, AsmInlineBlock *block, Ast *asm_stmt) { - if (platform_target.arch != ARCH_TYPE_X86_64 && platform_target.arch != ARCH_TYPE_AARCH64) + if (compiler.platform.arch != ARCH_TYPE_X86_64 && compiler.platform.arch != ARCH_TYPE_AARCH64) { SEMA_ERROR(asm_stmt, "Unsupported architecture for asm."); return false; } - init_asm(); - AsmInstruction *instr = asm_instr_by_name(asm_stmt->asm_stmt.instruction); + init_asm(&compiler.platform); + AsmInstruction *instr = asm_instr_by_name(&compiler.platform, asm_stmt->asm_stmt.instruction); if (!instr) { SEMA_ERROR(asm_stmt, "Unknown instruction"); diff --git a/src/compiler/sema_builtins.c b/src/compiler/sema_builtins.c index c272512ee..9f67a186a 100644 --- a/src/compiler/sema_builtins.c +++ b/src/compiler/sema_builtins.c @@ -276,7 +276,7 @@ static bool sema_expr_analyse_syscall(SemaContext *context, Expr *expr) if (!sema_analyse_expr_rhs(context, type_uptr, arg, true, NULL, false)) return false; optional = optional || type_is_optional(arg->type); } - switch (platform_target.arch) + switch (compiler.platform.arch) { case ARCH_TYPE_AARCH64: case ARCH_TYPE_AARCH64_BE: diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index a53491274..4e8aa359e 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -636,10 +636,10 @@ Type *cast_numeric_arithmetic_promotion(Type *type) switch (canonical->type_kind) { case ALL_SIGNED_INTS: - if (canonical->builtin.bitsize < platform_target.width_c_int) return type_cint; + if (canonical->builtin.bitsize < compiler.platform.width_c_int) return type_cint; return type; case ALL_UNSIGNED_INTS: - if (canonical->builtin.bitsize < platform_target.width_c_int) return type_cuint; + if (canonical->builtin.bitsize < compiler.platform.width_c_int) return type_cuint; return type; case TYPE_BF16: case TYPE_F16: @@ -1298,7 +1298,7 @@ static bool rule_vec_to_vec(CastContext *cc, bool is_explicit, bool is_silent) static bool rule_expand_to_vec(CastContext *cc, bool is_explicit, bool is_silent) { - if (!is_explicit && active_target.vector_conv == VECTOR_CONV_DEFAULT && !cc->is_binary_conversion) + if (!is_explicit && compiler.build.vector_conv == VECTOR_CONV_DEFAULT && !cc->is_binary_conversion) { if (is_silent) return false; bool explicit_works = rule_expand_to_vec(cc, true, true); diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index afe0102f6..0bd2b2b59 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -70,7 +70,7 @@ static bool sema_check_section(SemaContext *context, Attr *attr) Expr *expr = attr->exprs[0]; const char *section_string = expr->const_expr.bytes.ptr; // No restrictions except for MACH-O - if (platform_target.object_format != OBJ_FORMAT_MACHO) + if (compiler.platform.object_format != OBJ_FORMAT_MACHO) { return true; } @@ -443,7 +443,7 @@ RETRY:; case TYPE_FUNC_RAW: case TYPE_FAULTTYPE: case TYPE_SLICE: - return platform_target.align_pointer.align / 8; + return compiler.platform.align_pointer.align / 8; case TYPE_ENUM: type = type->decl->enums.type_info->type; goto RETRY; @@ -1789,7 +1789,7 @@ static inline bool unit_add_base_extension_method(SemaContext *context, Compilat switch (method->visibility) { case VISIBLE_PUBLIC: - vec_add(global_context.method_extensions, method); + vec_add(compiler.context.method_extensions, method); break; case VISIBLE_PRIVATE: vec_add(unit->module->private_method_extensions, method); @@ -1954,7 +1954,7 @@ static inline bool unit_add_method(SemaContext *context, Type *parent_type, Decl // Did we already define it externally? Decl *other = sema_find_extension_method_in_list(unit->local_method_extensions, parent_type, name); if (!other) sema_find_extension_method_in_list(unit->module->private_method_extensions, parent_type, name); - if (!other) sema_find_extension_method_in_list(global_context.method_extensions, parent_type, name); + if (!other) sema_find_extension_method_in_list(compiler.context.method_extensions, parent_type, name); if (other) { SEMA_ERROR(method, "This %s is already defined.", method_name_by_decl(method)); @@ -2314,7 +2314,7 @@ static bool update_call_abi_from_string(SemaContext *context, Decl *decl, Expr * // Check veccall if (str_eq(str, "veccall")) { - switch (platform_target.arch) + switch (compiler.platform.arch) { case ARCH_TYPE_X86_64: return update_abi(decl, CALL_X64_VECTOR); @@ -2334,7 +2334,7 @@ static bool update_call_abi_from_string(SemaContext *context, Decl *decl, Expr * // Finally check stdcall. if (strcmp(str, "stdcall") == 0) { - if (platform_target.arch == ARCH_TYPE_ARM || platform_target.arch == ARCH_TYPE_ARMB) + if (compiler.platform.arch == ARCH_TYPE_ARM || compiler.platform.arch == ARCH_TYPE_ARMB) { return update_abi(decl, CALL_AAPCS); } @@ -2924,15 +2924,15 @@ static inline bool sema_analyse_doc_header(SemaContext *context, AstId doc, } switch (directive->contract_stmt.param.modifier) { - case PARAM_ANY: + case INOUT_ANY: goto ADDED; - case PARAM_IN: + case INOUT_IN: param->var.in_param = true; break; - case PARAM_OUT: + case INOUT_OUT: param->var.out_param = true; break; - case PARAM_INOUT: + case INOUT_INOUT: break; } if (!may_be_pointer && type->type_kind != TYPE_SLICE) @@ -2948,7 +2948,7 @@ static inline MainType sema_find_main_type(SemaContext *context, Signature *sig, { Decl **params = sig->params; unsigned param_count = vec_size(params); - bool is_win32 = platform_target.os == OS_TYPE_WIN32; + bool is_win32 = compiler.platform.os == OS_TYPE_WIN32; Type *arg_type, *arg_type2; switch (param_count) { @@ -3161,7 +3161,7 @@ static inline bool sema_analyse_main_function(SemaContext *context, Decl *decl) { assert(decl != context->unit->main_function); bool is_winmain = decl->func_decl.attr_winmain; - bool is_win32 = platform_target.os == OS_TYPE_WIN32; + bool is_win32 = compiler.platform.os == OS_TYPE_WIN32; if (decl->visibility != VISIBLE_PUBLIC) { SEMA_ERROR(decl, "A main function must be public."); @@ -3192,9 +3192,9 @@ static inline bool sema_analyse_main_function(SemaContext *context, Decl *decl) // At this point the style is either MAIN_INT_VOID, MAIN_VOID_VOID or MAIN_ERR_VOID MainType type = sema_find_main_type(context, signature, is_winmain); if (type == MAIN_TYPE_ERROR) return false; - if (active_target.type == TARGET_TYPE_TEST || active_target.type == TARGET_TYPE_BENCHMARK) return true; + if (compiler.build.type == TARGET_TYPE_TEST || compiler.build.type == TARGET_TYPE_BENCHMARK) return true; Decl *function; - if (active_target.no_entry) + if (compiler.build.no_entry) { function = decl; goto REGISTER_MAIN; @@ -3204,7 +3204,7 @@ static inline bool sema_analyse_main_function(SemaContext *context, Decl *decl) RETURN_SEMA_ERROR(rtype_info, "Int return is required for a C style main."); } // Suppress winmain on non-win32 - if (platform_target.os != OS_TYPE_WIN32) is_winmain = false; + if (compiler.platform.os != OS_TYPE_WIN32) is_winmain = false; if ((type == MAIN_TYPE_RAW || type == MAIN_TYPE_NO_ARGS) && is_int_return && !is_winmain) { @@ -3216,20 +3216,20 @@ static inline bool sema_analyse_main_function(SemaContext *context, Decl *decl) goto REGISTER_MAIN; } bool use_wmain = is_win32 && !is_winmain && type != MAIN_TYPE_NO_ARGS; - active_target.win.use_win_subsystem = is_winmain && is_win32; + compiler.build.win.use_win_subsystem = is_winmain && is_win32; function = sema_create_synthetic_main(context, decl, type, is_int_return, is_err_return, is_winmain, use_wmain); if (!decl_ok(function)) return false; REGISTER_MAIN: context->unit->main_function = function; - if (global_context.main) + if (compiler.context.main) { SEMA_ERROR(function, "Duplicate main functions found."); - SEMA_NOTE(global_context.main, "The first one was found here."); + SEMA_NOTE(compiler.context.main, "The first one was found here."); return false; } else { - global_context.main = function; + compiler.context.main = function; } return true; } @@ -4210,7 +4210,7 @@ Decl *sema_analyse_parameterized_identifier(SemaContext *c, Path *decl_path, con sema_analyze_stage(instantiated_module, c->unit->module->stage - 1); } } - if (global_context.errors_found) return poisoned_decl; + if (compiler.context.errors_found) return poisoned_decl; Decl *symbol = module_find_symbol(instantiated_module, name); if (!symbol) { diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index ed986a6b1..2f1aba8bc 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -8,13 +8,6 @@ #define RETURN_SEMA_FUNC_ERROR(_decl, _node, ...) do { sema_error_at(context, (_node)->span, __VA_ARGS__); SEMA_NOTE(_decl, "The definition was here."); return false; } while (0) #define RETURN_NOTE_FUNC_DEFINITION do { SEMA_NOTE(callee->definition, "The definition was here."); return false; } while (0); -typedef enum -{ - SUBSCRIPT_EVAL_VALUE, - SUBSCRIPT_EVAL_REF, - SUBSCRIPT_EVAL_ASSIGN, - SUBSCRIPT_EVAL_VALID, -} SubscriptEval; typedef struct { @@ -7012,7 +7005,7 @@ static inline bool sema_expr_analyse_ct_and_or(SemaContext *context, Expr *expr, return true; } -typedef enum ConcatType_ +typedef enum { CONCAT_UNKNOWN, CONCAT_JOIN_BYTES, @@ -7894,7 +7887,7 @@ static inline bool sema_expr_analyse_compiler_const(SemaContext *context, Expr * UNREACHABLE case BUILTIN_DEF_NONE: { - Expr *value = htable_get(&global_context.compiler_defines, (void *)string); + Expr *value = htable_get(&compiler.context.compiler_defines, (void *)string); if (!value) { if (report_missing) @@ -7908,7 +7901,7 @@ static inline bool sema_expr_analyse_compiler_const(SemaContext *context, Expr * } case BUILTIN_DEF_BENCHMARK_NAMES: - if (!active_target.benchmarking) + if (!compiler.build.benchmarking) { expr->const_expr.const_kind = CONST_INITIALIZER; expr->expr_kind = EXPR_CONST; @@ -7923,7 +7916,7 @@ static inline bool sema_expr_analyse_compiler_const(SemaContext *context, Expr * expr->expr_kind = EXPR_BENCHMARK_HOOK; return true; case BUILTIN_DEF_BENCHMARK_FNS: - if (!active_target.benchmarking) + if (!compiler.build.benchmarking) { expr->const_expr.const_kind = CONST_INITIALIZER; expr->expr_kind = EXPR_CONST; @@ -7938,7 +7931,7 @@ static inline bool sema_expr_analyse_compiler_const(SemaContext *context, Expr * expr->expr_kind = EXPR_BENCHMARK_HOOK; return true; case BUILTIN_DEF_TEST_NAMES: - if (!active_target.testing) + if (!compiler.build.testing) { expr->const_expr.const_kind = CONST_INITIALIZER; expr->expr_kind = EXPR_CONST; @@ -7953,7 +7946,7 @@ static inline bool sema_expr_analyse_compiler_const(SemaContext *context, Expr * expr->expr_kind = EXPR_TEST_HOOK; return true; case BUILTIN_DEF_TEST_FNS: - if (!active_target.testing) + if (!compiler.build.testing) { expr->const_expr.const_kind = CONST_INITIALIZER; expr->expr_kind = EXPR_CONST; @@ -8545,7 +8538,7 @@ static inline bool sema_expr_analyse_embed(SemaContext *context, Expr *expr, boo if (!content) { if (!allow_fail) RETURN_SEMA_ERROR(expr, "Failed to load '%s'.", string); - if (!global_context.io_error_file_not_found) + if (!compiler.context.io_error_file_not_found) { Module *module = global_context_find_module(kw_std__io); Decl *io_error = module ? module_find_symbol(module, kw_IoError) : NULL; @@ -8561,9 +8554,9 @@ static inline bool sema_expr_analyse_embed(SemaContext *context, Expr *expr, boo } } } - global_context.io_error_file_not_found = fault; + compiler.context.io_error_file_not_found = fault; } - if (!decl_ok(global_context.io_error_file_not_found)) + if (!decl_ok(compiler.context.io_error_file_not_found)) { RETURN_SEMA_ERROR(expr, "Cannot generate an optional result, no IoError.FILE_NOT_FOUND could be located."); } @@ -8572,7 +8565,7 @@ static inline bool sema_expr_analyse_embed(SemaContext *context, Expr *expr, boo filename->expr_kind = EXPR_CONST; filename->const_expr.const_kind = CONST_ERR; expr->type = type_wildcard_optional; - filename->const_expr.enum_err_val = global_context.io_error_file_not_found; + filename->const_expr.enum_err_val = compiler.context.io_error_file_not_found; filename->resolve_status = RESOLVE_DONE; expr->resolve_status = RESOLVE_DONE; return true; @@ -8746,7 +8739,7 @@ static inline bool sema_expr_analyse_ct_feature(SemaContext *context, Expr *expr if (!inner->identifier_expr.is_const) goto ERROR; const char *name = inner->identifier_expr.ident; - void *value = htable_get(&global_context.features, (void *)name); + void *value = htable_get(&compiler.context.features, (void *)name); assert(!value || value == name); expr_rewrite_const_bool(expr, type_bool, value != NULL); return true; diff --git a/src/compiler/sema_internal.h b/src/compiler/sema_internal.h index 0f8d0b457..ecc954f5f 100644 --- a/src/compiler/sema_internal.h +++ b/src/compiler/sema_internal.h @@ -138,7 +138,7 @@ INLINE void sema_display_deprecated_warning_on_use(SemaContext *context, Decl *d // Prevent multiple reports decl->attrs_resolved->deprecated = NULL; - if (active_target.silence_deprecation) return; + if (compiler.build.silence_deprecation) return; if (msg[0]) { sema_warning_at(span, "'%s' is deprecated: %s.", decl->name, msg); diff --git a/src/compiler/sema_liveness.c b/src/compiler/sema_liveness.c index 279c3c41e..4e65f7901 100644 --- a/src/compiler/sema_liveness.c +++ b/src/compiler/sema_liveness.c @@ -451,18 +451,18 @@ RETRY: void sema_trace_liveness(void) { - if (global_context.main) + if (compiler.context.main) { - sema_trace_decl_liveness(global_context.main); + sema_trace_decl_liveness(compiler.context.main); } - bool keep_tests = active_target.testing; - bool keep_benchmarks = active_target.benchmarking; - FOREACH(Decl *, function, global_context.method_extensions) + bool keep_tests = compiler.build.testing; + bool keep_benchmarks = compiler.build.benchmarking; + FOREACH(Decl *, function, compiler.context.method_extensions) { if (function->func_decl.attr_dynamic) function->no_strip = true; if (function->is_export || function->no_strip) sema_trace_decl_liveness(function); } - FOREACH(Module *, module, global_context.module_list) + FOREACH(Module *, module, compiler.context.module_list) { FOREACH(CompilationUnit *, unit, module->units) { diff --git a/src/compiler/sema_name_resolution.c b/src/compiler/sema_name_resolution.c index 399fd5dea..d803fbb39 100644 --- a/src/compiler/sema_name_resolution.c +++ b/src/compiler/sema_name_resolution.c @@ -32,8 +32,8 @@ static inline bool matches_subpath(Path *path_to_check, Path *path_to_find) Decl *sema_decl_stack_resolve_symbol(const char *symbol) { - Decl **current = global_context.decl_stack_top; - Decl **end = global_context.decl_stack_bottom; + Decl **current = compiler.context.decl_stack_top; + Decl **end = compiler.context.decl_stack_bottom; while (current > end) { Decl *decl = *(--current); @@ -44,26 +44,26 @@ Decl *sema_decl_stack_resolve_symbol(const char *symbol) Decl **sema_decl_stack_store(void) { - Decl **current_bottom = global_context.decl_stack_bottom; - global_context.decl_stack_bottom = global_context.decl_stack_top; + Decl **current_bottom = compiler.context.decl_stack_bottom; + compiler.context.decl_stack_bottom = compiler.context.decl_stack_top; return current_bottom; } void sema_decl_stack_restore(Decl **state) { - global_context.decl_stack_top = global_context.decl_stack_bottom; - global_context.decl_stack_bottom = state; + compiler.context.decl_stack_top = compiler.context.decl_stack_bottom; + compiler.context.decl_stack_bottom = state; } void sema_decl_stack_push(Decl *decl) { - Decl **current = global_context.decl_stack_top; - if (current == &global_context.decl_stack[MAX_GLOBAL_DECL_STACK]) + Decl **current = compiler.context.decl_stack_top; + if (current == &compiler.context.decl_stack[MAX_GLOBAL_DECL_STACK]) { error_exit("Declaration stack exhausted."); } *(current++) = decl; - global_context.decl_stack_top = current; + compiler.context.decl_stack_top = current; } static void add_members_to_decl_stack(Decl *decl) @@ -385,10 +385,10 @@ static bool sema_resolve_path_symbol(SemaContext *context, NameResolve *name_res const char *symbol = name_resolve->symbol; // 0. std module special handling. - if (path->module == global_context.std_module_path.module) + if (path->module == compiler.context.std_module_path.module) { - name_resolve->path_found = &global_context.std_module; - name_resolve->found = module_find_symbol(&global_context.std_module, symbol); + name_resolve->path_found = &compiler.context.std_module; + name_resolve->found = module_find_symbol(&compiler.context.std_module, symbol); return true; } @@ -407,7 +407,7 @@ static bool sema_resolve_path_symbol(SemaContext *context, NameResolve *name_res // 4. Go to global search if (name_resolve->found) return true; - return sema_find_decl_in_global(context, &global_context.symbols, global_context.module_list, + return sema_find_decl_in_global(context, &compiler.context.symbols, compiler.context.module_list, name_resolve, false); } @@ -481,7 +481,7 @@ static bool sema_resolve_no_path_symbol(SemaContext *context, NameResolve *name_ if (!sema_find_decl_in_private_imports(context, name_resolve, false)) return false; if (name_resolve->found) return true; - return sema_find_decl_in_global(context, &global_context.symbols, NULL, name_resolve, false); + return sema_find_decl_in_global(context, &compiler.context.symbols, NULL, name_resolve, false); } #define MAX_TEST 256 @@ -675,7 +675,7 @@ INLINE bool sema_resolve_symbol_common(SemaContext *context, NameResolve *name_r { if (name_resolve->suppress_error) return true; Module *module_with_path = NULL; - FOREACH(Module *, module, global_context.module_list) + FOREACH(Module *, module, compiler.context.module_list) { if (matches_subpath(module->name, name_resolve->path)) { @@ -685,7 +685,7 @@ INLINE bool sema_resolve_symbol_common(SemaContext *context, NameResolve *name_r } if (!module_with_path) { - FOREACH(Module *, module, global_context.generic_module_list) + FOREACH(Module *, module, compiler.context.generic_module_list) { if (matches_subpath(module->name, name_resolve->path)) { @@ -734,13 +734,6 @@ Decl *sema_find_extension_method_in_list(Decl **extensions, Type *type, const ch return NULL; } -typedef enum -{ - METHOD_SEARCH_SUBMODULE_CURRENT, - METHOD_SEARCH_IMPORTED, - METHOD_SEARCH_CURRENT, - METHOD_SEARCH_PRIVATE_IMPORTED -} MethodSearchType; Decl *sema_resolve_method_in_module(Module *module, Type *actual_type, const char *method_name, @@ -916,8 +909,8 @@ Decl *sema_resolve_type_method(CompilationUnit *unit, Type *type, const char *me } if (!found) { - found = sema_resolve_method_in_module(global_context.core_module, type, method_name, - &private, &ambiguous, METHOD_SEARCH_IMPORTED); + found = sema_resolve_method_in_module(compiler.context.core_module, type, method_name, + &private, &ambiguous, METHOD_SEARCH_IMPORTED); } if (found && ambiguous) { @@ -926,7 +919,7 @@ Decl *sema_resolve_type_method(CompilationUnit *unit, Type *type, const char *me } if (!found) { - found = sema_find_extension_method_in_list(global_context.method_extensions, type, method_name); + found = sema_find_extension_method_in_list(compiler.context.method_extensions, type, method_name); private = NULL; } if (private) *private_ref = private; @@ -957,8 +950,8 @@ bool unit_resolve_parameterized_symbol(SemaContext *context, NameResolve *name_r if (!sema_find_decl_in_private_imports(context, name_resolve, true)) return false; if (!name_resolve->found) { - if (!sema_find_decl_in_global(context, &global_context.generic_symbols, - global_context.generic_module_list, + if (!sema_find_decl_in_global(context, &compiler.context.generic_symbols, + compiler.context.generic_module_list, name_resolve, true)) return false; } // 14. Error report diff --git a/src/compiler/sema_passes.c b/src/compiler/sema_passes.c index 2fdfd00e7..460b66c73 100644 --- a/src/compiler/sema_passes.c +++ b/src/compiler/sema_passes.c @@ -34,10 +34,10 @@ void sema_analyse_pass_module_hierarchy(Module *module) if (!slice.len) return; - unsigned module_count = vec_size(global_context.module_list); + unsigned module_count = vec_size(compiler.context.module_list); for (int i = 0; i < module_count; i++) { - Module *checked = global_context.module_list[i]; + Module *checked = compiler.context.module_list[i]; Path *checked_name = checked->name; if (checked_name->len != slice.len) continue; // Found the parent! We're done, we add this parent @@ -119,7 +119,7 @@ NEXT:; total_import_count += import_count; } (void)total_import_count; // workaround for clang 13.0 - DEBUG_LOG("Pass finished processing %d import(s) with %d error(s).", total_import_count, global_context.errors_found); + DEBUG_LOG("Pass finished processing %d import(s) with %d error(s).", total_import_count, compiler.context.errors_found); } INLINE void register_global_decls(CompilationUnit *unit, Decl **decls) @@ -153,13 +153,13 @@ INLINE File *sema_load_file(CompilationUnit *unit, SourceSpan span, Expr *filena print_error_at(span, "Failed to load file %s: %s", string, error); return NULL; } - if (global_context.errors_found) return NULL; + if (compiler.context.errors_found) return NULL; return file; } static Decl **sema_load_include(CompilationUnit *unit, Decl *decl) { - if (active_target.trust_level < TRUST_INCLUDE) + if (compiler.build.trust_level < TRUST_INCLUDE) { RETURN_PRINT_ERROR_AT(NULL, decl, "'$include' not permitted, trust level must be set to '--trust=include' or '--trust=full' to permit it."); } @@ -177,9 +177,9 @@ static Decl **sema_load_include(CompilationUnit *unit, Decl *decl) if (success) return NULL; File *file = sema_load_file(unit, decl->span, decl->include.filename, "$include", NULL); if (!file) return NULL; - if (global_context.includes_used++ > MAX_INCLUDES) + if (compiler.context.includes_used++ > MAX_INCLUDE_DIRECTIVES) { - RETURN_PRINT_ERROR_AT(NULL, decl, "This $include would cause the maximum number of includes (%d) to be exceeded.", MAX_INCLUDES); + RETURN_PRINT_ERROR_AT(NULL, decl, "This $include would cause the maximum number of includes (%d) to be exceeded.", MAX_INCLUDE_DIRECTIVES); } return parse_include_file(file, unit); } @@ -187,7 +187,7 @@ static Decl **sema_load_include(CompilationUnit *unit, Decl *decl) static Decl **sema_run_exec(CompilationUnit *unit, Decl *decl) { - if (active_target.trust_level < TRUST_FULL) + if (compiler.build.trust_level < TRUST_FULL) { RETURN_PRINT_ERROR_AT(NULL, decl, "'$exec' not permitted, trust level must be set to '--trust=full' to permit it."); } @@ -262,13 +262,13 @@ static Decl **sema_run_exec(CompilationUnit *unit, Decl *decl) File *file; // TODO fix Win32 char *old_path = NULL; - if (active_target.script_dir) + if (compiler.build.script_dir) { old_path = getcwd(NULL, 0); - if (!dir_change(active_target.script_dir)) + if (!dir_change(compiler.build.script_dir)) { free(old_path); - RETURN_PRINT_ERROR_AT(NULL, decl, "Failed to open script dir '%s'", active_target.script_dir); + RETURN_PRINT_ERROR_AT(NULL, decl, "Failed to open script dir '%s'", compiler.build.script_dir); } } if (c3_script) @@ -286,12 +286,12 @@ static Decl **sema_run_exec(CompilationUnit *unit, Decl *decl) free(old_path); if (!success) { - RETURN_PRINT_ERROR_AT(NULL, decl, "Failed to open run dir '%s'", active_target.script_dir); + RETURN_PRINT_ERROR_AT(NULL, decl, "Failed to open run dir '%s'", compiler.build.script_dir); } } - if (global_context.includes_used++ > MAX_INCLUDES) + if (compiler.context.includes_used++ > MAX_INCLUDE_DIRECTIVES) { - RETURN_PRINT_ERROR_AT(NULL, decl, "This $include would cause the maximum number of includes (%d) to be exceeded.", MAX_INCLUDES); + RETURN_PRINT_ERROR_AT(NULL, decl, "This $include would cause the maximum number of includes (%d) to be exceeded.", MAX_INCLUDE_DIRECTIVES); } return parse_include_file(file, unit); } @@ -354,7 +354,7 @@ void sema_analysis_pass_register_global_declarations(Module *module) assert(vec_size(unit->ct_includes) == 0); } - DEBUG_LOG("Pass finished with %d error(s).", global_context.errors_found); + DEBUG_LOG("Pass finished with %d error(s).", compiler.context.errors_found); } void sema_analysis_pass_register_conditional_units(Module *module) @@ -426,7 +426,7 @@ FAIL_CONTEXT: sema_context_destroy(&context); break; } - DEBUG_LOG("Pass finished with %d error(s).", global_context.errors_found); + DEBUG_LOG("Pass finished with %d error(s).", compiler.context.errors_found); } void sema_analysis_pass_register_conditional_declarations(Module *module) @@ -458,7 +458,7 @@ RETRY_INCLUDES: // We might have gotten more declarations. if (vec_size(unit->global_cond_decls) > 0) goto RETRY; } - DEBUG_LOG("Pass finished with %d error(s).", global_context.errors_found); + DEBUG_LOG("Pass finished with %d error(s).", compiler.context.errors_found); } void sema_analysis_pass_ct_assert(Module *module) @@ -480,7 +480,7 @@ void sema_analysis_pass_ct_assert(Module *module) sema_context_destroy(&context); if (!success) break; } - DEBUG_LOG("Pass finished with %d error(s).", global_context.errors_found); + DEBUG_LOG("Pass finished with %d error(s).", compiler.context.errors_found); } void sema_analysis_pass_ct_echo(Module *module) @@ -502,7 +502,7 @@ void sema_analysis_pass_ct_echo(Module *module) sema_context_destroy(&context); if (!success) break; } - DEBUG_LOG("Pass finished with %d error(s).", global_context.errors_found); + DEBUG_LOG("Pass finished with %d error(s).", compiler.context.errors_found); } static inline bool analyse_func_body(SemaContext *context, Decl *decl) @@ -514,10 +514,10 @@ static inline bool analyse_func_body(SemaContext *context, Decl *decl) return decl_poison(decl); } // Don't analyse functions that are tests. - if (decl->func_decl.attr_test && !active_target.testing) return true; + if (decl->func_decl.attr_test && !compiler.build.testing) return true; // Don't analyse functions that are benchmarks. - if (decl->func_decl.attr_benchmark && !active_target.benchmarking) return true; + if (decl->func_decl.attr_benchmark && !compiler.build.benchmarking) return true; if (!sema_analyse_function_body(context, decl)) return decl_poison(decl); return true; @@ -589,7 +589,7 @@ void sema_analysis_pass_decls(Module *module) } sema_context_destroy(&context); } - DEBUG_LOG("Pass finished with %d error(s).", global_context.errors_found); + DEBUG_LOG("Pass finished with %d error(s).", compiler.context.errors_found); } void sema_analysis_pass_lambda(Module *module) @@ -610,7 +610,7 @@ void sema_analysis_pass_lambda(Module *module) sema_context_destroy(&context); } - DEBUG_LOG("Pass finished with %d error(s).", global_context.errors_found); + DEBUG_LOG("Pass finished with %d error(s).", compiler.context.errors_found); } static inline bool sema_check_interfaces(SemaContext *context, Decl *decl) @@ -683,7 +683,7 @@ void sema_analysis_pass_interface(Module *module) sema_context_destroy(&context); } - DEBUG_LOG("Pass finished with %d error(s).", global_context.errors_found); + DEBUG_LOG("Pass finished with %d error(s).", compiler.context.errors_found); } void sema_analysis_pass_functions(Module *module) @@ -706,5 +706,5 @@ void sema_analysis_pass_functions(Module *module) sema_context_destroy(&context); } - DEBUG_LOG("Pass finished with %d error(s).", global_context.errors_found); + DEBUG_LOG("Pass finished with %d error(s).", compiler.context.errors_found); } diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index f7c3a02cb..cc08742e9 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -2204,7 +2204,7 @@ static inline bool sema_check_value_case(SemaContext *context, Type *switch_type return false; } Int128 range = int_sub(to_const_expr->ixx, const_expr->ixx).i; - Int128 max_range = { .low = active_target.switchrange_max_size }; + Int128 max_range = { .low = compiler.build.switchrange_max_size }; if (i128_comp(range, max_range, type_i128) == CMP_GT) { *max_ranged = true; diff --git a/src/compiler/semantic_analyser.c b/src/compiler/semantic_analyser.c index d0139e217..8cda586f0 100644 --- a/src/compiler/semantic_analyser.c +++ b/src/compiler/semantic_analyser.c @@ -133,14 +133,14 @@ void context_pop_defers_and_replace_ast(SemaContext *context, Ast *ast) static inline void halt_on_error(void) { - if (global_context.errors_found > 0) exit_compiler(EXIT_FAILURE); + if (compiler.context.errors_found > 0) exit_compiler(EXIT_FAILURE); } void sema_analyze_stage(Module *module, AnalysisStage stage) { while (module->stage < stage) { - global_context.decl_stack_bottom = global_context.decl_stack_top = global_context.decl_stack; + compiler.context.decl_stack_bottom = compiler.context.decl_stack_top = compiler.context.decl_stack; module->stage++; switch (module->stage) { @@ -182,7 +182,7 @@ void sema_analyze_stage(Module *module, AnalysisStage stage) case ANALYSIS_FINALIZE: break; } - if (global_context.errors_found) return; + if (compiler.context.errors_found) return; } } @@ -246,12 +246,12 @@ static void sema_analyze_to_stage(AnalysisStage stage) if (stage <= ANALYSIS_MODULE_TOP) { - FOREACH(Module *, module, global_context.generic_module_list) + FOREACH(Module *, module, compiler.context.generic_module_list) { sema_analyze_stage(module, stage); } } - FOREACH(Module *, module, global_context.module_list) + FOREACH(Module *, module, compiler.context.module_list) { sema_analyze_stage(module, stage); } @@ -260,14 +260,14 @@ static void sema_analyze_to_stage(AnalysisStage stage) static void assign_panicfn(void) { - if (active_target.feature.panic_level == PANIC_OFF || (!active_target.panicfn && no_stdlib())) + if (compiler.build.feature.panic_level == PANIC_OFF || (!compiler.build.panicfn && no_stdlib())) { - global_context.panic_var = NULL; - global_context.panicf = NULL; + compiler.context.panic_var = NULL; + compiler.context.panicf = NULL; return; } - const char *panicfn = active_target.panicfn ? active_target.panicfn : "std::core::builtin::panic"; + const char *panicfn = compiler.build.panicfn ? compiler.build.panicfn : "std::core::builtin::panic"; Path *path; const char *ident; TokenType type; @@ -275,7 +275,7 @@ static void assign_panicfn(void) { error_exit("'%s' is not a valid panic function.", panicfn); } - Decl *decl = sema_find_decl_in_modules(global_context.module_list, path, ident); + Decl *decl = sema_find_decl_in_modules(compiler.context.module_list, path, ident); if (!decl) { error_exit("Panic function pointer '%s::%s' could not be found.", path->module, ident); @@ -289,7 +289,7 @@ static void assign_panicfn(void) { error_exit("Expected panic function to have the signature fn void(String, String, String, uint)."); } - global_context.panic_var = decl; + compiler.context.panic_var = decl; decl->no_strip = true; if (no_stdlib()) return; @@ -299,10 +299,10 @@ static void assign_panicfn(void) { error_exit("'%s' is not a valid panicf function.", panicf); } - Decl *panicf_decl = sema_find_decl_in_modules(global_context.module_list, path, ident); + Decl *panicf_decl = sema_find_decl_in_modules(compiler.context.module_list, path, ident); if (!panicf_decl) { - global_context.panicf = NULL; + compiler.context.panicf = NULL; return; } @@ -318,18 +318,18 @@ static void assign_panicfn(void) { error_exit("Expected panic function to have the signature fn void(String, String, String, uint, ...)."); } - global_context.panicf = panicf_decl; + compiler.context.panicf = panicf_decl; } static void assign_testfn(void) { - if (!active_target.testing) return; - if (!active_target.testfn && no_stdlib()) + if (!compiler.build.testing) return; + if (!compiler.build.testfn && no_stdlib()) { - global_context.test_func = NULL; + compiler.context.test_func = NULL; return; } - const char *testfn = active_target.testfn ? active_target.testfn : "std::core::runtime::default_test_runner"; + const char *testfn = compiler.build.testfn ? compiler.build.testfn : "std::core::runtime::default_test_runner"; Path *path; const char *ident; TokenType type; @@ -337,7 +337,7 @@ static void assign_testfn(void) { error_exit("'%s' is not a valid test function.", testfn); } - Decl *decl = sema_find_decl_in_modules(global_context.module_list, path, ident); + Decl *decl = sema_find_decl_in_modules(compiler.context.module_list, path, ident); if (!decl) { error_exit("Test function '%s::%s' could not be found.", path->module, ident); @@ -350,19 +350,19 @@ static void assign_testfn(void) { error_exit("Expected test runner to have the signature fn void()."); } - global_context.test_func = decl; + compiler.context.test_func = decl; decl->no_strip = true; } static void assign_benchfn(void) { - if (!active_target.benchmarking) return; - if (!active_target.benchfn && no_stdlib()) + if (!compiler.build.benchmarking) return; + if (!compiler.build.benchfn && no_stdlib()) { - global_context.benchmark_func = NULL; + compiler.context.benchmark_func = NULL; return; } - const char *testfn = active_target.benchfn ? active_target.benchfn : "std::core::runtime::default_benchmark_runner"; + const char *testfn = compiler.build.benchfn ? compiler.build.benchfn : "std::core::runtime::default_benchmark_runner"; Path *path; const char *ident; TokenType type; @@ -370,7 +370,7 @@ static void assign_benchfn(void) { error_exit("'%s' is not a valid benchmark function.", testfn); } - Decl *decl = sema_find_decl_in_modules(global_context.module_list, path, ident); + Decl *decl = sema_find_decl_in_modules(compiler.context.module_list, path, ident); if (!decl) { error_exit("Benchmark function '%s::%s' could not be found.", path->module, ident); @@ -383,7 +383,7 @@ static void assign_benchfn(void) { error_exit("Expected benchmark function to have the signature fn void()."); } - global_context.benchmark_func = decl; + compiler.context.benchmark_func = decl; decl->no_strip = true; } @@ -392,31 +392,30 @@ static void assign_benchfn(void) */ void sema_analysis_run(void) { - compiler_parse(); // All global defines are added to the std module - global_context.std_module_path = (Path) { .module = kw_std, .span = INVALID_SPAN, .len = (uint32_t) strlen(kw_std) }; - global_context.std_module = (Module){ .name = &global_context.std_module_path }; - global_context.std_module.stage = ANALYSIS_LAST; - global_context.locals_list = NULL; + compiler.context.std_module_path = (Path) { .module = kw_std, .span = INVALID_SPAN, .len = (uint32_t) strlen(kw_std) }; + compiler.context.std_module = (Module){ .name = &compiler.context.std_module_path }; + compiler.context.std_module.stage = ANALYSIS_LAST; + compiler.context.locals_list = NULL; // Set a maximum of symbols in the std_module and test module - htable_init(&global_context.std_module.symbols, 0x1000); + htable_init(&compiler.context.std_module.symbols, 0x1000); // Set up the func prototype hash map type_func_prototype_init(0x10000); // Do we have zero modules? - if (!global_context.module_list) + if (!compiler.context.module_list) { - if (global_context.errors_found) exit_compiler(EXIT_FAILURE); + if (compiler.context.errors_found) exit_compiler(EXIT_FAILURE); error_exit("No modules to compile."); } // We parse the generic modules, just by storing the decls. - FOREACH(Module *, module, global_context.generic_module_list) + FOREACH(Module *, module, compiler.context.generic_module_list) { analyze_generic_module(module); } @@ -428,7 +427,7 @@ void sema_analysis_run(void) RESOLVE_LAMBDA:; bool found_lambda = false; - FOREACH(Module *, module, global_context.module_list) + FOREACH(Module *, module, compiler.context.module_list) { if (vec_size(module->lambdas_to_evaluate)) { @@ -447,10 +446,6 @@ RESOLVE_LAMBDA:; { sema_trace_liveness(); } - - - compiler_sema_time = bench_mark(); - } void sema_context_init(SemaContext *context, CompilationUnit *unit) @@ -479,19 +474,19 @@ void sema_context_destroy(SemaContext *context) Decl **global_context_acquire_locals_list(void) { - if (!vec_size(global_context.locals_list)) + if (!vec_size(compiler.context.locals_list)) { return VECNEW(Decl*, 64); } - Decl **result = VECLAST(global_context.locals_list); - vec_pop(global_context.locals_list); + Decl **result = VECLAST(compiler.context.locals_list); + vec_pop(compiler.context.locals_list); vec_resize(result, 0); return result; } void generic_context_release_locals_list(Decl **list) { - vec_add(global_context.locals_list, list); + vec_add(compiler.context.locals_list, list); } SemaContext *context_transform_for_eval(SemaContext *context, SemaContext *temp_context, CompilationUnit *eval_unit) diff --git a/src/compiler/source_file.c b/src/compiler/source_file.c index 8a02b2fe8..5857eacc1 100644 --- a/src/compiler/source_file.c +++ b/src/compiler/source_file.c @@ -17,21 +17,21 @@ static const size_t LEXER_FILES_START_CAPACITY = 128; File *source_file_by_id(FileId file) { - if (file == stdin_file_id) return &stdin_file; - assert(file < vec_size(global_context.loaded_sources)); - return global_context.loaded_sources[file]; + if (file == STDIN_FILE_ID) return &stdin_file; + assert(file < vec_size(compiler.context.loaded_sources)); + return compiler.context.loaded_sources[file]; } File *source_file_text_load(const char *filename, const char *content) { File *file = CALLOCS(File); - file->file_id = vec_size(global_context.loaded_sources); + file->file_id = vec_size(compiler.context.loaded_sources); file->full_path = str_copy(filename, strlen(filename)); file->contents = content; file->content_len = strlen(content); file->name = (char *)file->full_path; file->dir_path = str_copy("", 0); - vec_add(global_context.loaded_sources, file); + vec_add(compiler.context.loaded_sources, file); return file; } @@ -39,18 +39,18 @@ File *source_file_text_load(const char *filename, const char *content) File *source_file_generate(const char *filename) { File *file = CALLOCS(File); - file->file_id = vec_size(global_context.loaded_sources); + file->file_id = vec_size(compiler.context.loaded_sources); file->full_path = ""; file->contents = ""; file->content_len = 0; - vec_add(global_context.loaded_sources, file); + vec_add(compiler.context.loaded_sources, file); return file; } File *source_file_load(const char *filename, bool *already_loaded, const char **error) { if (already_loaded) *already_loaded = false; - if (!global_context.loaded_sources) global_context.loaded_sources = VECNEW(File*, LEXER_FILES_START_CAPACITY); + if (!compiler.context.loaded_sources) compiler.context.loaded_sources = VECNEW(File*, LEXER_FILES_START_CAPACITY); char* full_path = malloc_arena(PATH_MAX + 1); @@ -60,7 +60,7 @@ File *source_file_load(const char *filename, bool *already_loaded, const char ** return NULL; } - FOREACH(File *, file, global_context.loaded_sources) + FOREACH(File *, file, compiler.context.loaded_sources) { if (strcmp(file->full_path, full_path) == 0) { @@ -68,21 +68,21 @@ File *source_file_load(const char *filename, bool *already_loaded, const char ** return file; } } - if (vec_size(global_context.loaded_sources) == MAX_FILES) + if (vec_size(compiler.context.loaded_sources) == MAX_COMMAND_LINE_FILES) { - *error = str_printf("Exceeded max number of files %d", MAX_FILES); + *error = str_printf("Exceeded max number of files %d", MAX_COMMAND_LINE_FILES); return NULL; } size_t size; const char* source_text = file_read_all(filename, &size); File *file = CALLOCS(File); - file->file_id = vec_size(global_context.loaded_sources); + file->file_id = vec_size(compiler.context.loaded_sources); file->full_path = full_path; file->contents = source_text; file->content_len = size; file_get_dir_and_filename_from_full(file->full_path, &file->name, &file->dir_path); - vec_add(global_context.loaded_sources, file); + vec_add(compiler.context.loaded_sources, file); return file; } diff --git a/src/compiler/subprocess.c b/src/compiler/subprocess.c index 4ce9480d8..1b3854cda 100644 --- a/src/compiler/subprocess.c +++ b/src/compiler/subprocess.c @@ -33,24 +33,28 @@ int run_subprocess(const char *name, const char **args) scratch_buffer_clear(); scratch_buffer_printf("%s", name); - for (uint32_t i = 0; i < vec_size(args); i++) { + for (uint32_t i = 0; i < vec_size(args); i++) + { scratch_buffer_append_char(' '); bool need_quoting = strpbrk(args[i], "\t\v ") != NULL || args[i][0] == 0; if (need_quoting) scratch_buffer_append_char('"'); - for (int j = 0; '\0' != args[i][j]; j++) { - switch (args[i][j]) { - default: - break; - case '\\': - if (args[i][j + 1] == '"') { - scratch_buffer_append_char('\\'); - } + for (int j = 0; '\0' != args[i][j]; j++) + { + switch (args[i][j]) + { + default: + break; + case '\\': + if (args[i][j + 1] == '"') + { + scratch_buffer_append_char('\\'); + } - break; - case '"': - scratch_buffer_append_char('\\'); - break; + break; + case '"': + scratch_buffer_append_char('\\'); + break; } scratch_buffer_append_char(args[i][j]); @@ -71,7 +75,8 @@ int run_subprocess(const char *name, const char **args) &siStartInfo, &piProcInfo); - if (!bSuccess) { + if (!bSuccess) + { eprintf("Could not create child process: %lu", GetLastError()); return -1; } @@ -79,17 +84,19 @@ int run_subprocess(const char *name, const char **args) CloseHandle(piProcInfo.hThread); DWORD result = WaitForSingleObject( - piProcInfo.hProcess, // HANDLE hHandle, - INFINITE // DWORD dwMilliseconds - ); + piProcInfo.hProcess, // HANDLE hHandle, + INFINITE // DWORD dwMilliseconds + ); - if (result == WAIT_FAILED) { + if (result == WAIT_FAILED) + { eprintf("Could not wait on child process: %lu", GetLastError()); return -1; } DWORD exit_status; - if (!GetExitCodeProcess(piProcInfo.hProcess, &exit_status)) { + if (!GetExitCodeProcess(piProcInfo.hProcess, &exit_status)) + { eprintf("Could not get process exit code: %lu", GetLastError()); return -1; } diff --git a/src/compiler/target.c b/src/compiler/target.c index 27336e03b..687f7d001 100644 --- a/src/compiler/target.c +++ b/src/compiler/target.c @@ -26,11 +26,9 @@ static const char *x86features_as_string(X86Features *cpu_features); const X86Features x86_feature_zero = { { 0, 0}, NULL }; -PlatformTarget platform_target = { 0 }; - int target_alloca_addr_space() { - return platform_target.alloca_address_space; + return compiler.platform.alloca_address_space; } bool os_supports_stacktrace(OsType os_type) @@ -160,83 +158,83 @@ static bool os_target_signed_c_char_type(OsType os, ArchType arch) static inline void target_setup_arm_abi(void) { - platform_target.abi = ABI_ARM; - if (platform_target.os) + compiler.platform.abi = ABI_ARM; + if (compiler.platform.os) { - platform_target.arm.is_win32 = true; - platform_target.arm.variant = ARM_AAPCS; - platform_target.arm.abi_variant = ARM_ABI_AAPCS16_VFP; + compiler.platform.arm.is_win32 = true; + compiler.platform.arm.variant = ARM_AAPCS; + compiler.platform.arm.abi_variant = ARM_ABI_AAPCS16_VFP; return; } - if (platform_target.object_format == OBJ_FORMAT_MACHO) + if (compiler.platform.object_format == OBJ_FORMAT_MACHO) { - if (platform_target.environment_type == ENV_TYPE_EABI - || platform_target.os == OS_TYPE_UNKNOWN /* or is M */) + if (compiler.platform.environment_type == ENV_TYPE_EABI + || compiler.platform.os == OS_TYPE_UNKNOWN /* or is M */) { - platform_target.arm.variant = ARM_AAPCS; + compiler.platform.arm.variant = ARM_AAPCS; return; } // TODO if (/* is watch abi */ false) { - platform_target.arm.variant = ARM_AAPCS16; + compiler.platform.arm.variant = ARM_AAPCS16; goto SET_ABI; } - platform_target.arm.variant = ARM_APCS_GNU; + compiler.platform.arm.variant = ARM_APCS_GNU; goto SET_ABI; } - switch (platform_target.environment_type) + switch (compiler.platform.environment_type) { case ENV_TYPE_ANDROID: case ENV_TYPE_GNUEABI: case ENV_TYPE_GNUEABIHF: case ENV_TYPE_MUSLEABI: case ENV_TYPE_MUSLEABIHF: - platform_target.arm.variant = ARM_AAPCS_LINUX; + compiler.platform.arm.variant = ARM_AAPCS_LINUX; goto SET_ABI; case ENV_TYPE_EABI: case ENV_TYPE_EABIHF: - platform_target.arm.variant = ARM_AAPCS; + compiler.platform.arm.variant = ARM_AAPCS; goto SET_ABI; case ENV_TYPE_GNU: - platform_target.arm.variant = ARM_APCS_GNU; + compiler.platform.arm.variant = ARM_APCS_GNU; goto SET_ABI; default: break; } - switch (platform_target.os) + switch (compiler.platform.os) { case OS_TYPE_NETBSD: - platform_target.arm.variant = ARM_APCS_GNU; + compiler.platform.arm.variant = ARM_APCS_GNU; break; case OS_TYPE_OPENBSD: - platform_target.arm.variant = ARM_AAPCS_LINUX; + compiler.platform.arm.variant = ARM_AAPCS_LINUX; break; default: - platform_target.arm.variant = ARM_AAPCS; + compiler.platform.arm.variant = ARM_AAPCS; break; } SET_ABI: - switch (platform_target.arm.variant) + switch (compiler.platform.arm.variant) { case ARM_APCS_GNU: - platform_target.arm.abi_variant = ARM_ABI_APCS; + compiler.platform.arm.abi_variant = ARM_ABI_APCS; return; case ARM_AAPCS16: - platform_target.arm.abi_variant = ARM_ABI_AAPCS16_VFP; + compiler.platform.arm.abi_variant = ARM_ABI_AAPCS16_VFP; return; case ARM_AAPCS: case ARM_AAPCS_LINUX: - if (platform_target.float_abi == FLOAT_ABI_HARD || - (platform_target.float_abi != FLOAT_ABI_SOFT && - (platform_target.environment_type == ENV_TYPE_GNUEABIHF || - platform_target.environment_type == ENV_TYPE_MUSLEABIHF || - platform_target.environment_type == ENV_TYPE_EABIHF))) + if (compiler.platform.float_abi == FLOAT_ABI_HARD || + (compiler.platform.float_abi != FLOAT_ABI_SOFT && + (compiler.platform.environment_type == ENV_TYPE_GNUEABIHF || + compiler.platform.environment_type == ENV_TYPE_MUSLEABIHF || + compiler.platform.environment_type == ENV_TYPE_EABIHF))) { - platform_target.arm.abi_variant = ARM_ABI_AAPCS_VFP; + compiler.platform.arm.abi_variant = ARM_ABI_AAPCS_VFP; return; } - platform_target.arm.abi_variant = ARM_ABI_AAPCS; + compiler.platform.arm.abi_variant = ARM_ABI_AAPCS; break; } UNREACHABLE @@ -244,16 +242,16 @@ static inline void target_setup_arm_abi(void) static inline void target_setup_x86_abi(BuildTarget *target) { - platform_target.abi = ABI_X86; - platform_target.x86.use_soft_float = platform_target.float_abi == FLOAT_ABI_SOFT; + compiler.platform.abi = ABI_X86; + compiler.platform.x86.use_soft_float = compiler.platform.float_abi == FLOAT_ABI_SOFT; // Build target override. if (target->feature.soft_float != SOFT_FLOAT_DEFAULT) { - platform_target.x86.use_soft_float = target->feature.soft_float == SOFT_FLOAT_YES; + compiler.platform.x86.use_soft_float = target->feature.soft_float == SOFT_FLOAT_YES; } - platform_target.x86.is_mcu_api = platform_target.os == OS_TYPE_ELFIAMCU; - switch (platform_target.os) + compiler.platform.x86.is_mcu_api = compiler.platform.os == OS_TYPE_ELFIAMCU; + switch (compiler.platform.os) { case OS_TYPE_MACOSX: case OS_TYPE_IOS: @@ -264,14 +262,14 @@ static inline void target_setup_x86_abi(BuildTarget *target) case OS_TYPE_ELFIAMCU: case OS_TYPE_OPENBSD: case OS_TYPE_WIN32: - platform_target.x86.return_small_struct_in_reg_abi = true; + compiler.platform.x86.return_small_struct_in_reg_abi = true; break; default: break; } if (target->feature.x86_struct_return != STRUCT_RETURN_DEFAULT) { - platform_target.x86.return_small_struct_in_reg_abi = target->feature.x86_struct_return == STRUCT_RETURN_REG; + compiler.platform.x86.return_small_struct_in_reg_abi = target->feature.x86_struct_return == STRUCT_RETURN_REG; } } @@ -936,9 +934,9 @@ static X86CpuSet x64_cpu_default(void) static inline void target_setup_x64_abi(BuildTarget *target) { - platform_target.abi = ABI_X64; + compiler.platform.abi = ABI_X64; X86CpuSet cpu_set; - platform_target.x64.is_win64 = platform_target.os == OS_TYPE_WIN32; + compiler.platform.x64.is_win64 = compiler.platform.os == OS_TYPE_WIN32; bool is_native = target->arch_os_target == default_target; if (!is_native && target->feature.x86_cpu_set == X86CPU_NATIVE) target->feature.x86_cpu_set = X86CPU_DEFAULT; if (target->feature.x86_cpu_set != X86CPU_DEFAULT) @@ -952,42 +950,42 @@ static inline void target_setup_x64_abi(BuildTarget *target) INFO_LOG("Set default CPU as %s\n", x86_cpu_set[cpu_set]); } - platform_target.cpu = x86_cpu_from_set(cpu_set); + compiler.platform.cpu = x86_cpu_from_set(cpu_set); X86Features cpu_features; x86features_from_cpu(&cpu_features, cpu_set); x64features_limit_from_capability(&cpu_features, target->feature.x86_vector_capability); - if (target->feature.soft_float == SOFT_FLOAT_YES) platform_target.x64.soft_float = true; - if (target->feature.pass_win64_simd_as_arrays == WIN64_SIMD_ARRAY) platform_target.x64.win64_simd_as_array = true; + if (target->feature.soft_float == SOFT_FLOAT_YES) compiler.platform.x64.soft_float = true; + if (target->feature.pass_win64_simd_as_arrays == WIN64_SIMD_ARRAY) compiler.platform.x64.win64_simd_as_array = true; scratch_buffer_clear(); x86features_as_diff_to_scratch(&cpu_features, cpu_set); - if (platform_target.x64.soft_float) scratch_buffer_append("+soft-float,"); + if (compiler.platform.x64.soft_float) scratch_buffer_append("+soft-float,"); if (scratch_buffer.len > 0) scratch_buffer.len--; - platform_target.features = scratch_buffer_copy(); + compiler.platform.features = scratch_buffer_copy(); - if (platform_target.environment_type == ENV_TYPE_GNU) + if (compiler.platform.environment_type == ENV_TYPE_GNU) { //platform_target.x64.is_mingw64 = platform_target.x64.is_win64; - if (platform_target.x64.is_win64) DEBUG_LOG("Mingw"); + if (compiler.platform.x64.is_win64) DEBUG_LOG("Mingw"); } - if (platform_target.os == OS_TYPE_LINUX || platform_target.os == OS_TYPE_NETBSD) + if (compiler.platform.os == OS_TYPE_LINUX || compiler.platform.os == OS_TYPE_NETBSD) { - platform_target.x64.pass_int128_vector_in_mem = true; + compiler.platform.x64.pass_int128_vector_in_mem = true; } - platform_target.x64.features = cpu_features; + compiler.platform.x64.features = cpu_features; if (x64features_contains(&cpu_features, X86_FEAT_AVX512F)) { - platform_target.x64.native_vector_size_avx = 64; - platform_target.x64.align_simd_default = 512; + compiler.platform.x64.native_vector_size_avx = 64; + compiler.platform.x64.align_simd_default = 512; } else if (x64features_contains(&cpu_features, X86_FEAT_AVX)) { - platform_target.x64.native_vector_size_avx = 32; - platform_target.x64.align_simd_default = 256; + compiler.platform.x64.native_vector_size_avx = 32; + compiler.platform.x64.align_simd_default = 256; } else if (x64features_contains(&cpu_features, X86_FEAT_SSE)) { - platform_target.x64.native_vector_size_avx = 16; - platform_target.x64.align_simd_default = 128; + compiler.platform.x64.native_vector_size_avx = 16; + compiler.platform.x64.align_simd_default = 128; } } @@ -1739,14 +1737,14 @@ static bool arch_os_pic_default_forced(ArchType arch, OsType os) INLINE const char *llvm_macos_target_triple(const char *triple) { - if (active_target.macos.min_version) + if (compiler.build.macos.min_version) { scratch_buffer_clear(); scratch_buffer_append(triple); - scratch_buffer_append(active_target.macos.min_version); + scratch_buffer_append(compiler.build.macos.min_version); return scratch_buffer_to_string(); } - MacSDK *mac_sdk = active_target.macos.sdk; + MacSDK *mac_sdk = compiler.build.macos.sdk; if (!mac_sdk) { @@ -1786,14 +1784,14 @@ void *llvm_target_machine_create(void) } char *err = NULL; LLVMTargetRef target = NULL; - if (LLVMGetTargetFromTriple(platform_target.target_triple, &target, &err) != 0) + if (LLVMGetTargetFromTriple(compiler.platform.target_triple, &target, &err) != 0) { - error_exit("Could not create target: %s for triple '%s'", err, platform_target.target_triple); + error_exit("Could not create target: %s for triple '%s'", err, compiler.platform.target_triple); // Usually we would dispose of err, but no need to do it due to exit. } LLVMRelocMode reloc_mode = LLVMRelocDefault; - switch (platform_target.reloc_model) + switch (compiler.platform.reloc_model) { case RELOC_SMALL_PIC: case RELOC_BIG_PIC: @@ -1808,12 +1806,12 @@ void *llvm_target_machine_create(void) default: UNREACHABLE } - INFO_LOG("CPU: %s", platform_target.cpu); - INFO_LOG("Features: %s", platform_target.features); - LLVMCodeModel model = active_target.kernel_build ? LLVMCodeModelKernel : LLVMCodeModelDefault; - void *result = LLVMCreateTargetMachine(target, platform_target.target_triple, - platform_target.cpu ? platform_target.cpu : "", platform_target.features ? platform_target.features : "", - (LLVMCodeGenOptLevel)platform_target.llvm_opt_level, + INFO_LOG("CPU: %s", compiler.platform.cpu); + INFO_LOG("Features: %s", compiler.platform.features); + LLVMCodeModel model = compiler.build.kernel_build ? LLVMCodeModelKernel : LLVMCodeModelDefault; + void *result = LLVMCreateTargetMachine(target, compiler.platform.target_triple, + compiler.platform.cpu ? compiler.platform.cpu : "", compiler.platform.features ? compiler.platform.features : "", + (LLVMCodeGenOptLevel)compiler.platform.llvm_opt_level, reloc_mode, model); LLVMSetTargetMachineUseInitArray(result, true); if (!result) error_exit("Failed to create target machine."); @@ -1844,10 +1842,10 @@ void target_setup(BuildTarget *target) error_exit("Xtensa support is not available with this LLVM version."); } - platform_target.target_triple = arch_to_target_triple[target->arch_os_target]; - assert(platform_target.target_triple); + compiler.platform.target_triple = arch_to_target_triple[target->arch_os_target]; + assert(compiler.platform.target_triple); - platform_target.alloca_address_space = 0; + compiler.platform.alloca_address_space = 0; // Create a specific target machine LLVMCodeGenOptLevel level; @@ -1872,88 +1870,88 @@ void target_setup(BuildTarget *target) UNREACHABLE; } - platform_target.llvm_opt_level = (int)level; - INFO_LOG("Triple picked was %s.", platform_target.target_triple); + compiler.platform.llvm_opt_level = (int)level; + INFO_LOG("Triple picked was %s.", compiler.platform.target_triple); INFO_LOG("Default was %s.", LLVM_DEFAULT_TARGET_TRIPLE); - StringSlice target_triple_string = slice_from_string(platform_target.target_triple); - platform_target.arch = arch_from_llvm_string(slice_next_token(&target_triple_string, '-')); - if (!arch_is_supported(platform_target.arch)) + StringSlice target_triple_string = slice_from_string(compiler.platform.target_triple); + compiler.platform.arch = arch_from_llvm_string(slice_next_token(&target_triple_string, '-')); + if (!arch_is_supported(compiler.platform.arch)) { printf("WARNING! This architecture is unsupported.\n"); } - platform_target.vendor = vendor_from_llvm_string(slice_next_token(&target_triple_string, '-')); - platform_target.os = os_from_llvm_string(slice_next_token(&target_triple_string, '-')); - platform_target.environment_type = environment_type_from_llvm_string(target_triple_string); + compiler.platform.vendor = vendor_from_llvm_string(slice_next_token(&target_triple_string, '-')); + compiler.platform.os = os_from_llvm_string(slice_next_token(&target_triple_string, '-')); + compiler.platform.environment_type = environment_type_from_llvm_string(target_triple_string); if (target->debug_info == DEBUG_INFO_NOT_SET) { target->debug_info = DEBUG_INFO_FULL; } - platform_target.float_abi = false; + compiler.platform.float_abi = false; // TLS should not be supported for: // ARM Cygwin // NVPTX - platform_target.tls_supported = os_target_use_thread_local(platform_target.os); - platform_target.big_endian = arch_big_endian(platform_target.arch); - platform_target.width_pointer = arch_pointer_bit_width(platform_target.os, platform_target.arch); - platform_target.width_register = arch_int_register_bit_width(platform_target.os, platform_target.arch); - platform_target.alloca_address_space = 0; - platform_target.object_format = object_format_from_os(platform_target.os, platform_target.arch); - switch (platform_target.object_format) + compiler.platform.tls_supported = os_target_use_thread_local(compiler.platform.os); + compiler.platform.big_endian = arch_big_endian(compiler.platform.arch); + compiler.platform.width_pointer = arch_pointer_bit_width(compiler.platform.os, compiler.platform.arch); + compiler.platform.width_register = arch_int_register_bit_width(compiler.platform.os, compiler.platform.arch); + compiler.platform.alloca_address_space = 0; + compiler.platform.object_format = object_format_from_os(compiler.platform.os, compiler.platform.arch); + switch (compiler.platform.object_format) { case OBJ_FORMAT_COFF: case OBJ_FORMAT_ELF: case OBJ_FORMAT_WASM: - platform_target.use_comdat = true; + compiler.platform.use_comdat = true; break; default: break; } if (!target->cc) { - target->cc = platform_target.os == OS_TYPE_WIN32 ? "cl.exe" : "cc"; + target->cc = compiler.platform.os == OS_TYPE_WIN32 ? "cl.exe" : "cc"; } - platform_target.int128 = os_target_supports_int128(platform_target.os, platform_target.arch); - platform_target.vec128f = os_target_supports_vec(platform_target.os, platform_target.arch, 128, false); - platform_target.vec128i = os_target_supports_vec(platform_target.os, platform_target.arch, 128, true); - platform_target.vec64f = os_target_supports_vec(platform_target.os, platform_target.arch, 64, false); - platform_target.vec64i = os_target_supports_vec(platform_target.os, platform_target.arch, 64, true); - platform_target.float128 = os_target_supports_float128(platform_target.os, platform_target.arch); - platform_target.float16 = os_target_supports_float16(platform_target.os, platform_target.arch); + compiler.platform.int128 = os_target_supports_int128(compiler.platform.os, compiler.platform.arch); + compiler.platform.vec128f = os_target_supports_vec(compiler.platform.os, compiler.platform.arch, 128, false); + compiler.platform.vec128i = os_target_supports_vec(compiler.platform.os, compiler.platform.arch, 128, true); + compiler.platform.vec64f = os_target_supports_vec(compiler.platform.os, compiler.platform.arch, 64, false); + compiler.platform.vec64i = os_target_supports_vec(compiler.platform.os, compiler.platform.arch, 64, true); + compiler.platform.float128 = os_target_supports_float128(compiler.platform.os, compiler.platform.arch); + compiler.platform.float16 = os_target_supports_float16(compiler.platform.os, compiler.platform.arch); for (BitSizes i = BITS8; i < BITSIZES_LEN; i++) { unsigned bits = (unsigned) (8 << (i - 1)); - platform_target.integers[i] = os_target_alignment_of_int(platform_target.os, platform_target.arch, bits); - platform_target.floats[i] = os_target_alignment_of_float(platform_target.os, platform_target.arch, bits); + compiler.platform.integers[i] = os_target_alignment_of_int(compiler.platform.os, compiler.platform.arch, bits); + compiler.platform.floats[i] = os_target_alignment_of_float(compiler.platform.os, compiler.platform.arch, bits); } - platform_target.integers[BIT1] = platform_target.integers[BITS8]; + compiler.platform.integers[BIT1] = compiler.platform.integers[BITS8]; - platform_target.align_pointer = (AlignData) { platform_target.width_pointer, platform_target.width_pointer }; - platform_target.width_c_short = os_target_c_type_bits(platform_target.os, platform_target.arch, CTYPE_SHORT); - platform_target.width_c_int = os_target_c_type_bits(platform_target.os, platform_target.arch, CTYPE_INT); - platform_target.width_c_long = os_target_c_type_bits(platform_target.os, platform_target.arch, CTYPE_LONG); - platform_target.width_c_long_long = os_target_c_type_bits(platform_target.os, platform_target.arch, CTYPE_LONG_LONG); - platform_target.signed_c_char = os_target_signed_c_char_type(platform_target.os, platform_target.arch); - switch (platform_target.arch) + compiler.platform.align_pointer = (AlignData) { compiler.platform.width_pointer, compiler.platform.width_pointer }; + compiler.platform.width_c_short = os_target_c_type_bits(compiler.platform.os, compiler.platform.arch, CTYPE_SHORT); + compiler.platform.width_c_int = os_target_c_type_bits(compiler.platform.os, compiler.platform.arch, CTYPE_INT); + compiler.platform.width_c_long = os_target_c_type_bits(compiler.platform.os, compiler.platform.arch, CTYPE_LONG); + compiler.platform.width_c_long_long = os_target_c_type_bits(compiler.platform.os, compiler.platform.arch, CTYPE_LONG_LONG); + compiler.platform.signed_c_char = os_target_signed_c_char_type(compiler.platform.os, compiler.platform.arch); + switch (compiler.platform.arch) { case ARCH_UNSUPPORTED: UNREACHABLE break; case ARCH_TYPE_AARCH64: case ARCH_TYPE_AARCH64_BE: - platform_target.aarch.is_darwin = os_is_apple(platform_target.os); - platform_target.aarch.is_win32 = platform_target.os == OS_TYPE_WIN32; - platform_target.abi = ABI_AARCH64; + compiler.platform.aarch.is_darwin = os_is_apple(compiler.platform.os); + compiler.platform.aarch.is_win32 = compiler.platform.os == OS_TYPE_WIN32; + compiler.platform.abi = ABI_AARCH64; break; case ARCH_TYPE_XTENSA: - platform_target.abi = ABI_XTENSA; + compiler.platform.abi = ABI_XTENSA; break; case ARCH_TYPE_WASM32: case ARCH_TYPE_WASM64: - platform_target.abi = ABI_WASM; + compiler.platform.abi = ABI_WASM; break; case ARCH_TYPE_ARMB: case ARCH_TYPE_ARM: @@ -1965,103 +1963,103 @@ void target_setup(BuildTarget *target) FATAL_ERROR("PPC32 is not supported."); case ARCH_TYPE_PPC64: case ARCH_TYPE_PPC64LE: - if (platform_target.object_format != OBJ_FORMAT_ELF) + if (compiler.platform.object_format != OBJ_FORMAT_ELF) { - if (platform_target.arch == ARCH_TYPE_PPC64LE) + if (compiler.platform.arch == ARCH_TYPE_PPC64LE) { FATAL_ERROR("PPC64 LE non-ELF not supported."); } FATAL_ERROR("PPC64 not supported"); } /** Here we need to have different codegen depending on elf version :( */ - platform_target.abi = ABI_PPC64_SVR4; - platform_target.ppc64.is_softfp = platform_target.float_abi == FLOAT_ABI_SOFT; + compiler.platform.abi = ABI_PPC64_SVR4; + compiler.platform.ppc64.is_softfp = compiler.platform.float_abi == FLOAT_ABI_SOFT; /* todo enable if elfv2 */ - platform_target.ppc64.is_elfv2 = platform_target.arch == ARCH_TYPE_PPC64LE; + compiler.platform.ppc64.is_elfv2 = compiler.platform.arch == ARCH_TYPE_PPC64LE; /* todo enable if elfv1-qpx */ - platform_target.ppc64.has_qpx = false; + compiler.platform.ppc64.has_qpx = false; break; case ARCH_TYPE_RISCV64: case ARCH_TYPE_RISCV32: - platform_target.riscv.xlen = arch_pointer_bit_width(platform_target.os, platform_target.arch) / 8; // pointer width + compiler.platform.riscv.xlen = arch_pointer_bit_width(compiler.platform.os, compiler.platform.arch) / 8; // pointer width switch (target->feature.riscv_float_capability) { case RISCVFLOAT_DEFAULT: - platform_target.riscv.flen = 0; + compiler.platform.riscv.flen = 0; break; case RISCVFLOAT_NONE: case RISCVFLOAT_FLOAT: case RISCVFLOAT_DOUBLE: - platform_target.riscv.flen = 4 * target->feature.riscv_float_capability; + compiler.platform.riscv.flen = 4 * target->feature.riscv_float_capability; break; } - platform_target.abi = ABI_RISCV; + compiler.platform.abi = ABI_RISCV; break; case ARCH_TYPE_X86: target_setup_x86_abi(target); break; case ARCH_TYPE_X86_64: target_setup_x64_abi(target); - if (platform_target.os == OS_TYPE_WIN32) + if (compiler.platform.os == OS_TYPE_WIN32) { - platform_target.abi = ABI_WIN64; + compiler.platform.abi = ABI_WIN64; break; } - platform_target.abi = ABI_X64; + compiler.platform.abi = ABI_X64; break; case ARCH_TYPE_UNKNOWN: - platform_target.abi = ABI_UNKNOWN; + compiler.platform.abi = ABI_UNKNOWN; break; } - platform_target.align_max_vector = os_arch_max_alignment_of_vector(platform_target.os, - platform_target.arch, - platform_target.environment_type, - platform_target.arm.variant, - &platform_target.x64.features); - platform_target.align_max_tls = os_arch_max_alignment_of_tls(platform_target.os, - platform_target.arch, - platform_target.environment_type); - platform_target.reloc_model = arch_os_reloc_default(platform_target.arch, - platform_target.os, - platform_target.environment_type, - active_target.type != TARGET_TYPE_EXECUTABLE); - platform_target.pic_required = arch_os_pic_default_forced(platform_target.arch, platform_target.os); + compiler.platform.align_max_vector = os_arch_max_alignment_of_vector(compiler.platform.os, + compiler.platform.arch, + compiler.platform.environment_type, + compiler.platform.arm.variant, + &compiler.platform.x64.features); + compiler.platform.align_max_tls = os_arch_max_alignment_of_tls(compiler.platform.os, + compiler.platform.arch, + compiler.platform.environment_type); + compiler.platform.reloc_model = arch_os_reloc_default(compiler.platform.arch, + compiler.platform.os, + compiler.platform.environment_type, + compiler.build.type != TARGET_TYPE_EXECUTABLE); + compiler.platform.pic_required = arch_os_pic_default_forced(compiler.platform.arch, compiler.platform.os); // Override PIC, but only if the platform does not require PIC if (target->reloc_model != RELOC_DEFAULT - && (target->reloc_model != RELOC_NONE || !platform_target.pic_required)) + && (target->reloc_model != RELOC_NONE || !compiler.platform.pic_required)) { - platform_target.reloc_model = target->reloc_model; + compiler.platform.reloc_model = target->reloc_model; } - if (platform_target.os == OS_TYPE_MACOSX) + if (compiler.platform.os == OS_TYPE_MACOSX) { - if (!active_target.macos.sysroot) active_target.macos.sysroot = macos_sysroot(); - const char *sysroot = active_target.macos.sysroot ? active_target.macos.sysroot : macos_sysroot(); + if (!compiler.build.macos.sysroot) compiler.build.macos.sysroot = macos_sysroot(); + const char *sysroot = compiler.build.macos.sysroot ? compiler.build.macos.sysroot : macos_sysroot(); - active_target.macos.sdk = NULL; + compiler.build.macos.sdk = NULL; if (sysroot) { INFO_LOG("Macos SDK: %s", sysroot); - active_target.macos.sdk = macos_sysroot_sdk_information(sysroot); - if (platform_target.arch == ARCH_TYPE_AARCH64) + compiler.build.macos.sdk = macos_sysroot_sdk_information(sysroot); + if (compiler.platform.arch == ARCH_TYPE_AARCH64) { - if (active_target.macos.sdk->macos_min_deploy_target.major < 11) + if (compiler.build.macos.sdk->macos_min_deploy_target.major < 11) { - active_target.macos.sdk->macos_min_deploy_target = (Version) { 11, 0 }; + compiler.build.macos.sdk->macos_min_deploy_target = (Version) { 11, 0 }; } - if (active_target.macos.sdk->macos_deploy_target.major < 11) + if (compiler.build.macos.sdk->macos_deploy_target.major < 11) { - active_target.macos.sdk->macos_deploy_target = (Version) { 11, 0 }; + compiler.build.macos.sdk->macos_deploy_target = (Version) { 11, 0 }; } } } - platform_target.target_triple = strdup(llvm_macos_target_triple(platform_target.target_triple)); + compiler.platform.target_triple = strdup(llvm_macos_target_triple(compiler.platform.target_triple)); } - assert(platform_target.reloc_model != RELOC_DEFAULT); + assert(compiler.platform.reloc_model != RELOC_DEFAULT); // TODO remove - type_setup(&platform_target); + type_setup(&compiler.platform); } diff --git a/src/compiler/target.h b/src/compiler/target.h index d67221c35..b3023919e 100644 --- a/src/compiler/target.h +++ b/src/compiler/target.h @@ -1,234 +1,15 @@ #pragma once - -// Copyright (c) 2020 Christoffer Lerno. All rights reserved. +// Copyright (c) 2020-2024 Christoffer Lerno. All rights reserved. // Use of this source code is governed by a LGPLv3.0 // a copy of which can be found in the LICENSE file. - -// Note: This list is based on Clang's -typedef enum -{ - ARCH_TYPE_UNKNOWN, - ARCH_TYPE_ARM, // ARM (little endian): arm, armv.*, xscale - ARCH_TYPE_ARMB, // ARM (big endian): armeb - ARCH_TYPE_AARCH64, // AArch64 (little endian): aarch64 - ARCH_TYPE_AARCH64_BE, // AArch64 (big endian): aarch64_be - ARCH_TYPE_AARCH64_32, // AArch64 (little endian) ILP32: aarch64_32 - ARCH_TYPE_ARC, // ARC: Synopsys ARC - ARCH_TYPE_AVR, // AVR: Atmel AVR microcontroller - ARCH_TYPE_BPFEL, // eBPF or extended BPF or 64-bit BPF (little endian) - ARCH_TYPE_BPFEB, // eBPF or extended BPF or 64-bit BPF (big endian) - ARCH_TYPE_HEXAGON, // Hexagon: hexagon - ARCH_TYPE_MIPS, // MIPS: mips, mipsallegrex, mipsr6 - ARCH_TYPE_MIPSEL, // MIPSEL: mipsel, mipsallegrexe, mipsr6el - ARCH_TYPE_MIPS64, // MIPS64: mips64, mips64r6, mipsn32, mipsn32r6 - ARCH_TYPE_MIPS64EL, // MIPS64EL: mips64el, mips64r6el, mipsn32el, mipsn32r6el - ARCH_TYPE_MSP430, // MSP430: msp430 - ARCH_TYPE_PPC, // PPC: powerpc - ARCH_TYPE_PPC64, // PPC64: powerpc64, ppu - ARCH_TYPE_PPC64LE, // PPC64LE: powerpc64le - ARCH_TYPE_R600, // R600: AMD GPUs HD2XXX - HD6XXX - ARCH_TYPE_AMDGCN, // AMDGCN: AMD GCN GPUs - ARCH_TYPE_RISCV32, // RISC-V (32-bit): riscv32 - ARCH_TYPE_RISCV64, // RISC-V (64-bit): riscv64 - ARCH_TYPE_SPARC, // Sparc: sparc - ARCH_TYPE_SPARCV9, // Sparcv9: Sparcv9 - ARCH_TYPE_SPARCEL, // Sparc: (endianness = little). NB: 'Sparcle' is a CPU variant - ARCH_TYPE_SYSTEMZ, // SystemZ: s390x - ARCH_TYPE_TCE, // TCE (http://tce.cs.tut.fi/): tce - ARCH_TYPE_TCELE, // TCE little endian (http://tce.cs.tut.fi/): tcele - ARCH_TYPE_THUMB, // Thumb (little endian): thumb, thumbv.* - ARCH_TYPE_THUMBEB, // Thumb (big endian): thumbeb - ARCH_TYPE_X86, // X86: i[3-9]86 - ARCH_TYPE_X86_64, // X86-64: amd64, x86_64 - ARCH_TYPE_XCORE, // XCore: xcore - ARCH_TYPE_NVPTX, // NVPTX: 32-bit - ARCH_TYPE_NVPTX64, // NVPTX: 64-bit - ARCH_TYPE_LE32, // le32: generic little-endian 32-bit CPU (PNaCl) - ARCH_TYPE_LE64, // le64: generic little-endian 64-bit CPU (PNaCl) - ARCH_TYPE_AMDIL, // AMDIL - ARCH_TYPE_AMDIL64, // AMDIL with 64-bit pointers - ARCH_TYPE_HSAIL, // AMD HSAIL - ARCH_TYPE_HSAIL64, // AMD HSAIL with 64-bit pointers - ARCH_TYPE_SPIR, // SPIR: standard portable IR for OpenCL 32-bit version - ARCH_TYPE_SPIR64, // SPIR: standard portable IR for OpenCL 64-bit version - ARCH_TYPE_KALIMBA, // Kalimba: generic kalimba - ARCH_TYPE_SHAVE, // SHAVE: Movidius vector VLIW processors - ARCH_TYPE_LANAI, // Lanai: Lanai 32-bit - ARCH_TYPE_WASM32, // WebAssembly with 32-bit pointers - ARCH_TYPE_WASM64, // WebAssembly with 64-bit pointers - ARCH_TYPE_RSCRIPT32, // 32-bit RenderScript - ARCH_TYPE_RSCRIPT64, // 64-bit RenderScript - ARCH_TYPE_XTENSA, // Xtensa - ARCH_TYPE_LAST = ARCH_TYPE_XTENSA - -} ArchType; - -#define ARCH_UNSUPPORTED ARCH_TYPE_AARCH64_32: case ARCH_TYPE_BPFEL: case ARCH_TYPE_BPFEB: case ARCH_TYPE_SPARCEL: \ - case ARCH_TYPE_LE64: case ARCH_TYPE_AMDIL: case ARCH_TYPE_AMDIL64: case ARCH_TYPE_HSAIL: case ARCH_TYPE_HSAIL64: \ - case ARCH_TYPE_KALIMBA: case ARCH_TYPE_SHAVE: case ARCH_TYPE_RSCRIPT32: case ARCH_TYPE_RSCRIPT64: \ - case ARCH_TYPE_LE32: case ARCH_TYPE_MIPS: case ARCH_TYPE_MIPSEL: case ARCH_TYPE_MIPS64EL: case ARCH_TYPE_MIPS64: \ - case ARCH_TYPE_AVR: case ARCH_TYPE_NVPTX64: case ARCH_TYPE_NVPTX: case ARCH_TYPE_MSP430: case ARCH_TYPE_SYSTEMZ: \ - case ARCH_TYPE_TCELE: case ARCH_TYPE_TCE: case ARCH_TYPE_LANAI: case ARCH_TYPE_HEXAGON: case ARCH_TYPE_AMDGCN: \ - case ARCH_TYPE_R600: case ARCH_TYPE_SPARC: case ARCH_TYPE_SPARCV9: case ARCH_TYPE_XCORE: case ARCH_TYPE_ARC: \ - case ARCH_TYPE_SPIR64: case ARCH_TYPE_SPIR - -typedef enum -{ - CTYPE_SHORT, - CTYPE_INT, - CTYPE_LONG, - CTYPE_LONG_LONG -} CType; - -typedef enum -{ - OS_TYPE_UNKNOWN, - OS_TYPE_NONE, - OS_TYPE_ANANAS, - OS_TYPE_CLOUD_ABI, - OS_TYPE_DRAGON_FLY, - OS_TYPE_FREE_BSD, - OS_TYPE_FUCHSIA, - OS_TYPE_IOS, - OS_TYPE_KFREEBSD, - OS_TYPE_LINUX, - OS_TYPE_PS3, - OS_TYPE_MACOSX, - OS_TYPE_NETBSD, - OS_TYPE_OPENBSD, - OS_TYPE_SOLARIS, - OS_TYPE_WIN32, - OS_TYPE_HAIKU, - OS_TYPE_MINIX, - OS_TYPE_RTEMS, - OS_TYPE_NACL, // Native Client - OS_TYPE_CNK, // BG/P Compute-Node Kernel - OS_TYPE_AIX, - OS_TYPE_CUDA, - OS_TYPE_NVOPENCL, - OS_TYPE_AMDHSA, - OS_TYPE_PS4, - OS_TYPE_ELFIAMCU, - OS_TYPE_TVOS, - OS_TYPE_WATCHOS, - OS_TYPE_MESA3D, - OS_TYPE_CONTIKI, - OS_TYPE_AMDPAL, - OS_TYPE_HERMITCORE, - OS_TYPE_HURD, - OS_TYPE_WASI, - OS_TYPE_EMSCRIPTEN, - OS_TYPE_LAST = OS_TYPE_EMSCRIPTEN -} OsType; - -#define OS_DARWIN_TYPES OS_TYPE_WATCHOS: case OS_TYPE_IOS: case OS_TYPE_TVOS: case OS_TYPE_MACOSX -#define OS_UNSUPPORTED OS_TYPE_AIX: case OS_TYPE_HAIKU: case OS_TYPE_ANANAS: case OS_TYPE_CLOUD_ABI: \ - case OS_TYPE_DRAGON_FLY: case OS_TYPE_FUCHSIA: case OS_TYPE_KFREEBSD: case OS_TYPE_PS3: case OS_TYPE_RTEMS: \ - case OS_TYPE_SOLARIS: case OS_TYPE_MINIX: case OS_TYPE_NACL: case OS_TYPE_CNK: case OS_TYPE_CUDA: \ - case OS_TYPE_NVOPENCL: case OS_TYPE_AMDHSA: case OS_TYPE_PS4: case OS_TYPE_ELFIAMCU: case OS_TYPE_MESA3D: \ - case OS_TYPE_CONTIKI: case OS_TYPE_AMDPAL: case OS_TYPE_HERMITCORE: case OS_TYPE_HURD: case OS_TYPE_EMSCRIPTEN - -typedef enum -{ - ENV_TYPE_UNKNOWN, - ENV_TYPE_GNU, - ENV_TYPE_GNUABIN32, - ENV_TYPE_GNUABI64, - ENV_TYPE_GNUEABI, - ENV_TYPE_GNUEABIHF, - ENV_TYPE_GNUX32, - ENV_TYPE_CODE16, - ENV_TYPE_EABI, - ENV_TYPE_EABIHF, - ENV_TYPE_ELFV1, - ENV_TYPE_ELFV2, - ENV_TYPE_ANDROID, - ENV_TYPE_MUSL, - ENV_TYPE_MUSLEABI, - ENV_TYPE_MUSLEABIHF, - ENV_TYPE_MSVC, - ENV_TYPE_ITANIUM, - ENV_TYPE_CYGNUS, - ENV_TYPE_CORECLR, - ENV_TYPE_SIMULATOR, - ENV_TYPE_MACABI, - ENV_TYPE_LAST = ENV_TYPE_MACABI -} EnvironmentType; - -typedef enum -{ - OBJ_FORMAT_UNSUPPORTED, - OBJ_FORMAT_COFF, - OBJ_FORMAT_GOFF, - OBJ_FORMAT_ELF, - OBJ_FORMAT_MACHO, - OBJ_FORMAT_WASM, - OBJ_FORMAT_XCOFF, - OBJ_FORMAT_AOUT, -} ObjectFormatType; - -typedef enum -{ - VENDOR_UNKNOWN, - VENDOR_APPLE, - VENDOR_PC, - VENDOR_SCEI, - VENDOR_BGP, - VENDOR_BGQ, - VENDOR_FREESCALE, - VENDOR_IBM, - VENDOR_IMAGINATION_TECHNOLOGIES, - VENDOR_MIPS_TECHNOLOGIES, - VENDOR_NVIDIA, - VENDOR_CSR, - VENDOR_MYRIAD, - VENDOR_AMD, - VENDOR_MESA, - VENDOR_SUSE, - VENDOR_OPEN_EMBEDDED, - VENDOR_LAST = VENDOR_OPEN_EMBEDDED -} VendorType; - -typedef enum -{ - ABI_UNKNOWN, - ABI_X64, - ABI_WIN64, - ABI_X86, - ABI_AARCH64, - ABI_WASM, - ABI_ARM, - ABI_PPC32, - ABI_PPC64_SVR4, - ABI_RISCV, - ABI_XTENSA, -} ABI; - - -typedef enum -{ - FLOAT_ABI_NONE, - FLOAT_ABI_SOFT, - FLOAT_ABI_HARD, -} FloatABI; - - -typedef enum -{ - ARM_AAPCS, - ARM_AAPCS16, - ARM_APCS_GNU, - ARM_AAPCS_LINUX, -} ARMVariant; - -typedef enum -{ - ARM_ABI_AAPCS, - ARM_ABI_APCS, - ARM_ABI_AAPCS16_VFP, - ARM_ABI_AAPCS_VFP, -} ARMABIVariant; +#define MAX_ASM_INSTRUCTION_PARAMS 6 +#define CLOBBER_FLAG_ELEMENTS 4 +#define MAX_CLOBBER_FLAGS (64 * CLOBBER_FLAG_ELEMENTS) +#define ASM_INSTRUCTION_MAX 0x1000 +#define ASM_INSTRUCTION_MASK (ASM_INSTRUCTION_MAX - 1) +#define ASM_REGISTER_MAX 4096 +#define ASM_REGISTER_MASK (ASM_REGISTER_MAX - 1) typedef struct { @@ -236,17 +17,17 @@ typedef struct unsigned pref_align; } AlignData; -typedef enum +typedef struct { - BIT1, - BITS8, - BITS16, - BITS32, - BITS64, - BITS128, - BITS256, - BITSIZES_LEN -} BitSizes; + bool is_write : 1; + bool is_readwrite : 1; + bool is_address : 1; + AsmArgBits imm_arg_ubits : 16; + AsmArgBits imm_arg_ibits : 16; + AsmArgBits ireg_bits : 16; + AsmArgBits float_bits : 16; + AsmArgBits vec_bits : 16; +} AsmArgType; typedef struct X86Features { @@ -254,6 +35,33 @@ typedef struct X86Features const char *as_string; } X86Features; +typedef struct +{ + uint64_t mask[CLOBBER_FLAG_ELEMENTS]; +} Clobbers; + +typedef struct +{ + char string[1024]; + unsigned constraint_len; +} ClobberList; + +typedef struct +{ + const char *name; + AsmRegisterType type; + AsmArgBits bits; + int clobber_index; +} AsmRegister; + +typedef struct +{ + const char *name; + AsmArgType param[MAX_ASM_INSTRUCTION_PARAMS]; + unsigned param_count; + Clobbers mask; +} AsmInstruction; + typedef struct { const char *target_triple; @@ -366,6 +174,13 @@ typedef struct char *platform_name; // MinGlobalAlign is used by Clang for SystemZ and Lanai targets. + bool asm_initialized; + const char **clobber_name_list; + const char *extra_clobbers; + AsmRegister registers[ASM_REGISTER_MAX]; + AsmInstruction instructions[ASM_INSTRUCTION_MAX]; + unsigned register_count; + } PlatformTarget; static inline bool is_pie_pic(RelocModel reloc) @@ -384,119 +199,4 @@ static inline bool is_pie_pic(RelocModel reloc) UNREACHABLE } -typedef enum X64Feature -{ - X86_FEAT_ADX, - X86_FEAT_AES, - X86_FEAT_AMX_BF16, - X86_FEAT_AMX_COMPLEX, - X86_FEAT_AMX_FP16, - X86_FEAT_AMX_INT8, - X86_FEAT_AMX_TILE, - X86_FEAT_AVX, - X86_FEAT_AVX10_1_512, - X86_FEAT_AVX10_1_256, - X86_FEAT_AVX2, - X86_FEAT_AVX5124FMAPS, - X86_FEAT_AVX5124VNNIW, - X86_FEAT_AVX512BF16, - X86_FEAT_AVX512BITALG, - X86_FEAT_AVX512BW, - X86_FEAT_AVX512CD, - X86_FEAT_AVX512DQ, - X86_FEAT_AVX512ER, - X86_FEAT_AVX512F, - X86_FEAT_AVX512FP16, - X86_FEAT_AVX512IFMA, - X86_FEAT_AVX512PF, - X86_FEAT_AVX512VBMI, - X86_FEAT_AVX512VBMI2, - X86_FEAT_AVX512VL, - X86_FEAT_AVX512VNNI, - X86_FEAT_AVX512VP2INTERSECT, - X86_FEAT_AVX512VPOPCNTDQ, - X86_FEAT_AVXIFMA, - X86_FEAT_AVXNECONVERT, - X86_FEAT_AVXVNNI, - X86_FEAT_AVXVNNIINT16, - X86_FEAT_AVXVNNIINT8, - X86_FEAT_BMI, - X86_FEAT_BMI2, - X86_FEAT_CLDEMOTE, - X86_FEAT_CLFLUSHOPT, - X86_FEAT_CLWB, - X86_FEAT_CLZERO, - X86_FEAT_CMOV, - X86_FEAT_CMPCCXADD, - X86_FEAT_CMPXCHG16B, - X86_FEAT_CMPXCHG8B, - X86_FEAT_CRC32, - X86_FEAT_ENQCMD, - X86_FEAT_EVEX512, - X86_FEAT_F16C, - X86_FEAT_FMA, - X86_FEAT_FMA4, - X86_FEAT_FSGSBASE, - X86_FEAT_FXSR, - X86_FEAT_GFNI, - X86_FEAT_HRESET, - X86_FEAT_INVPCID, - X86_FEAT_KL, - X86_FEAT_LWP, - X86_FEAT_LZCNT, - X86_FEAT_MMX, - X86_FEAT_MOVBE, - X86_FEAT_MOVDIR64B, - X86_FEAT_MOVDIRI, - X86_FEAT_MWAITX, - X86_FEAT_PCLMUL, - X86_FEAT_PCONFIG, - X86_FEAT_PKU, - X86_FEAT_POPCNT, - X86_FEAT_PREFETCHI, - X86_FEAT_PREFETCHWT1, - X86_FEAT_PRFCHW, - X86_FEAT_PTWRITE, - X86_FEAT_RAOINT, - X86_FEAT_RDPID, - X86_FEAT_RDPRU, - X86_FEAT_RDRND, - X86_FEAT_RDSEED, - X86_FEAT_RTM, - X86_FEAT_SAHF, - X86_FEAT_SERIALIZE, - X86_FEAT_SGX, - X86_FEAT_SHA, - X86_FEAT_SHA512, - X86_FEAT_SHSTK, - X86_FEAT_SM3, - X86_FEAT_SM4, - X86_FEAT_SSE, - X86_FEAT_SSE2, - X86_FEAT_SSE3, - X86_FEAT_SSE4_1, - X86_FEAT_SSE4_2, - X86_FEAT_SSE4_A, - X86_FEAT_SSSE3, - X86_FEAT_TBM, - X86_FEAT_TSXLDTRK, - X86_FEAT_UINTR, - X86_FEAT_USERMSR, - X86_FEAT_VAES, - X86_FEAT_VPCLMULQDQ, - X86_FEAT_VZEROUPPER, - X86_FEAT_WAITPKG, - X86_FEAT_WBNOINVD, - X86_FEAT_WIDEKL, - X86_FEAT_X87, - X86_FEAT_XOP, - X86_FEAT_XSAVE, - X86_FEAT_XSAVEC, - X86_FEAT_XSAVEOPT, - X86_FEAT_XSAVES, - X86_FEATURE_LAST = X86_FEAT_XSAVES, -} X86Feature; - - -extern PlatformTarget platform_target; diff --git a/src/compiler/types.c b/src/compiler/types.c index db66f1086..f2ac6f63b 100644 --- a/src/compiler/types.c +++ b/src/compiler/types.c @@ -67,8 +67,8 @@ Type *type_cuint; void type_init_cint(void) { - type_cint = type_int_signed_by_bitsize(platform_target.width_c_int); - type_cuint = type_int_unsigned_by_bitsize(platform_target.width_c_int); + type_cint = type_int_signed_by_bitsize(compiler.platform.width_c_int); + type_cuint = type_int_unsigned_by_bitsize(compiler.platform.width_c_int); } Type *type_int_signed_by_bitsize(BitSize bitsize) @@ -1264,7 +1264,7 @@ static void type_create_alias(const char *name, Type *location, Type *canonical) Decl *decl = decl_new(DECL_TYPEDEF, name, INVALID_SPAN); decl->resolve_status = RESOLVE_DONE; decl->typedef_decl.type_info = type_info_new_base(canonical, INVALID_SPAN); - decl->unit = global_context.core_unit; + decl->unit = compiler.context.core_unit; decl->is_export = true; *location = (Type) { .decl = decl, @@ -1289,13 +1289,13 @@ Type *type_new_func(Decl *decl, Signature *sig) static inline void type_init_int(const char *name, Type *type, TypeKind kind, BitSizes bits) { unsigned actual_bits = bits ? (unsigned int)(8 << (bits - 1)) : 1; - type_init(name, type, kind, actual_bits, platform_target.integers[bits]); + type_init(name, type, kind, actual_bits, compiler.platform.integers[bits]); } static inline void type_create_float(const char *name, Type *type, TypeKind kind, BitSizes bits) { unsigned actual_bits = bits ? (unsigned int)(8 << (bits - 1)) : 1; - type_init(name, type, kind, actual_bits, platform_target.floats[bits]); + type_init(name, type, kind, actual_bits, compiler.platform.floats[bits]); } void type_setup(PlatformTarget *target) @@ -1346,7 +1346,7 @@ void type_setup(PlatformTarget *target) type_chars = type_get_slice(type_char); type_wildcard_optional = type_get_optional(type_wildcard); Decl *string_decl = decl_new_with_type(symtab_preset("String", TOKEN_TYPE_IDENT), INVALID_SPAN, DECL_DISTINCT); - string_decl->unit = global_context.core_unit; + string_decl->unit = compiler.context.core_unit; string_decl->extname = string_decl->name; string_decl->is_substruct = true; string_decl->distinct = type_info_new_base(type_chars, INVALID_SPAN);