diff --git a/src/compiler.bbb b/src/compiler.bbb index 620797f..a04fcf9 100644 --- a/src/compiler.bbb +++ b/src/compiler.bbb @@ -1012,6 +1012,7 @@ CompileFile = struct relative_file_path: []u8, build_mode: BuildMode, has_debug_info: u1, + host_cpu_model: u1, silent: u1, } @@ -1031,11 +1032,16 @@ Target = struct { cpu: CPUArchitecture, os: OperatingSystem, + host_cpu_model: u1, } -target_get_native = fn () Target +target_get_native = fn (host_cpu_model: u1) Target { - return { .cpu = .x86_64, .os = .linux }; + return { + .cpu = .x86_64, + .os = .linux, + .host_cpu_model = host_cpu_model, + }; } target_compare = fn (a: Target, b: Target) u1 @@ -17179,11 +17185,20 @@ emit = fn (module: &Module) void >cpu_model: &u8 = zero; >cpu_features: &u8 = zero; - if (target_compare(module.target, target_get_native())) + if (target_compare(module.target, target_get_native(module.target.host_cpu_model))) { target_triple = host_target_triple; - cpu_model = host_cpu_model; - cpu_features = host_cpu_features; + + if (module.target.host_cpu_model) + { + cpu_model = host_cpu_model; + cpu_features = host_cpu_features; + } + else + { + cpu_model = "generic"; + cpu_features = ""; + } } else { @@ -18273,30 +18288,45 @@ compile_file = fn (arena: &Arena, compile_options: CompileFile, envp: &&u8) []u8 >base_name = relative_file_path[base_start..extension_start]; >is_compiler = string_equal(relative_file_path, "src/compiler.bbb"); + + os_make_directory(base_cache_dir.pointer); + >base_dir = arena_join_string(arena, [ base_cache_dir, "/", - #enum_name(#build_mode), - "_", - #select(#has_debug_info(), "di", "nodi"), - ][..]); - >outputh_path_dir = arena_join_string(arena, [ - base_dir, - #select(is_compiler, "/compiler/", "/"), - #enum_name(compile_options.build_mode), - "_", - #select(compile_options.has_debug_info, "di", "nodi"), + #select(compile_options.host_cpu_model, "native", "generic"), + ][..]); + + os_make_directory(base_dir.pointer); + + base_dir = arena_join_string(arena, [ + base_dir, + "/", + #enum_name(#build_mode), + "_", + #select(#has_debug_info(), "di", "nodi"), ][..]); - os_make_directory(base_cache_dir.pointer); os_make_directory(base_dir.pointer); if (is_compiler) { - >compiler_dir = arena_join_string(arena, [ base_dir, "/compiler" ][..]); - os_make_directory(compiler_dir.pointer); + base_dir = arena_join_string(arena, [ + base_dir, + "/compiler", + ][..]); + + os_make_directory(base_dir.pointer); } + >outputh_path_dir = arena_join_string(arena, [ + base_dir, + "/", + #enum_name(compile_options.build_mode), + "_", + #select(compile_options.has_debug_info, "di", "nodi"), + ][..]); + os_make_directory(outputh_path_dir.pointer); >outputh_path_base = arena_join_string(arena, [ outputh_path_dir, "/", base_name ][..]); @@ -18456,7 +18486,7 @@ compile_file = fn (arena: &Arena, compile_options: CompileFile, envp: &&u8) []u8 .content = file_content, .path = file_path, .has_debug_info = compile_options.has_debug_info, - .target = target_get_native(), + .target = target_get_native(compile_options.host_cpu_model), .silent = compile_options.silent, }; @@ -18608,6 +18638,7 @@ names: [_][]u8 = } >debug_info_array: [_]u1 = [1, 0]; + >is_host_cpu_model_array: [_]u1 = [1, 0]; >command = command_string_to_enum.enum_value; @@ -18661,6 +18692,7 @@ names: [_][]u8 = compile_file(arena, { .relative_file_path = relative_file_path, .build_mode = build_mode, + .host_cpu_model = 0, .has_debug_info = has_debug_info, .silent = 0, }, envp); @@ -18673,6 +18705,47 @@ names: [_][]u8 = } for (name: names) + { + for (is_host_cpu_model: is_host_cpu_model_array) + { + for (build_mode: #enum_values(BuildMode)) + { + for (has_debug_info: debug_info_array) + { + >position = arena.position; + + >relative_file_path = arena_join_string(arena, [ "tests/", name, ".bbb" ][..]); + >executable_path = compile_file(arena, { + .relative_file_path = relative_file_path, + .build_mode = build_mode, + .has_debug_info = has_debug_info, + .host_cpu_model = is_host_cpu_model, + .silent = 1, + }, envp); + + >arguments: [_]&u8 = [ + executable_path.pointer, + zero, + ]; + >args = arguments[..arguments.length - 1]; + >execution = os_execute(arena, args, envp, zero); + + >success = execution.termination_kind == .exit and execution.termination_code == 0; + + if (!success) + { + #trap(); + } + + arena.position = position; + } + } + } + } + }, + .reproduce => + { + for (is_host_cpu_model: is_host_cpu_model_array) { for (build_mode: #enum_values(BuildMode)) { @@ -18680,16 +18753,20 @@ names: [_][]u8 = { >position = arena.position; - >relative_file_path = arena_join_string(arena, [ "tests/", name, ".bbb" ][..]); + // Produce the compiler + >relative_file_path = "src/compiler.bbb"; >executable_path = compile_file(arena, { - .relative_file_path = relative_file_path, - .build_mode = build_mode, - .has_debug_info = has_debug_info, - .silent = 1, - }, envp); + .relative_file_path = relative_file_path, + .host_cpu_model = is_host_cpu_model, + .build_mode = build_mode, + .has_debug_info = has_debug_info, + .silent = 1, + }, envp); + // Test the compiler >arguments: [_]&u8 = [ executable_path.pointer, + "test", zero, ]; >args = arguments[..arguments.length - 1]; @@ -18707,43 +18784,6 @@ names: [_][]u8 = } } }, - .reproduce => - { - for (build_mode: #enum_values(BuildMode)) - { - for (has_debug_info: debug_info_array) - { - >position = arena.position; - - // Produce the compiler - >relative_file_path = "src/compiler.bbb"; - >executable_path = compile_file(arena, { - .relative_file_path = relative_file_path, - .build_mode = build_mode, - .has_debug_info = has_debug_info, - .silent = 1, - }, envp); - - // Test the compiler - >arguments: [_]&u8 = [ - executable_path.pointer, - "test", - zero, - ]; - >args = arguments[..arguments.length - 1]; - >execution = os_execute(arena, args, envp, zero); - - >success = execution.termination_kind == .exit and execution.termination_code == 0; - - if (!success) - { - #trap(); - } - - arena.position = position; - } - } - }, } return 0; diff --git a/src/compiler.cpp b/src/compiler.cpp index 876235a..f6c0a38 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -163,22 +163,39 @@ fn String compile_file(Arena* arena, Compile options) auto is_compiler = relative_file_path.equal(string_literal("src/compiler.bbb")); - String output_path_dir_parts[] = { + make_directory(base_cache_dir); + + String cpu_dir_parts[] = { string_literal(base_cache_dir), - is_compiler ? string_literal("/compiler/") : string_literal("/"), + string_literal("/"), + options.host_cpu_model ? string_literal("native") : string_literal("generic"), + }; + + auto cpu_dir = arena_join_string(arena, array_to_slice(cpu_dir_parts)); + + make_directory(cstr(cpu_dir)); + + auto base_dir = cpu_dir; + + if (is_compiler) + { + String compiler_dir_parts[] = { + base_dir, + string_literal("/compiler"), + }; + base_dir = arena_join_string(arena, array_to_slice(compiler_dir_parts)); + make_directory(cstr(base_dir)); + } + + String output_path_dir_parts[] = { + base_dir, + string_literal("/"), build_mode_to_string(options.build_mode), string_literal("_"), options.has_debug_info ? string_literal("di") : string_literal("nodi"), }; auto output_path_dir = arena_join_string(arena, array_to_slice(output_path_dir_parts)); - make_directory(base_cache_dir); - - if (is_compiler) - { - make_directory(base_cache_dir "/compiler"); - } - make_directory(cstr(output_path_dir)); String output_path_base_parts[] = { @@ -341,6 +358,7 @@ fn String compile_file(Arena* arena, Compile options) .target = { .cpu = CPUArchitecture::x86_64, .os = OperatingSystem::linux_, + .host_cpu_model = options.host_cpu_model, }, .build_mode = options.build_mode, .has_debug_info = options.has_debug_info, @@ -583,43 +601,48 @@ void entry_point(Slice arguments, Slice envp) } bool has_debug_info_array[] = {true, false}; + bool is_host_cpu_model_array[] = {true, false}; for (auto name: names) { - for (BuildMode build_mode = BuildMode::debug_none; build_mode < BuildMode::count; build_mode = (BuildMode)((backing_type(BuildMode))build_mode + 1)) + for (auto is_host_cpu_model : is_host_cpu_model_array) { - for (bool has_debug_info : has_debug_info_array) + for (BuildMode build_mode = BuildMode::debug_none; build_mode < BuildMode::count; build_mode = (BuildMode)((backing_type(BuildMode))build_mode + 1)) { - auto position = arena->position; - - String relative_file_path_parts[] = { string_literal("tests/"), name, string_literal(".bbb") }; - auto relative_file_path = arena_join_string(arena, array_to_slice(relative_file_path_parts)); - - auto executable_path = compile_file(arena, { - .relative_file_path = relative_file_path, - .build_mode = build_mode, - .has_debug_info = has_debug_info, - .silent = true, - }); - - char* const arguments[] = + for (bool has_debug_info : has_debug_info_array) { - (char*)executable_path.pointer, - 0, - }; - Slice arg_slice = array_to_slice(arguments); - arg_slice.length -= 1; - auto execution = os_execute(arena, arg_slice, environment, {}); - auto success = execution.termination_kind == TerminationKind::exit && execution.termination_code == 0; - if (!success) - { - print(string_literal("Test failed: ")); - print(executable_path); - print(string_literal("\n")); - bb_fail(); + auto position = arena->position; + + String relative_file_path_parts[] = { string_literal("tests/"), name, string_literal(".bbb") }; + auto relative_file_path = arena_join_string(arena, array_to_slice(relative_file_path_parts)); + + auto executable_path = compile_file(arena, { + .relative_file_path = relative_file_path, + .build_mode = build_mode, + .has_debug_info = has_debug_info, + .host_cpu_model = is_host_cpu_model, + .silent = true, + }); + + char* const arguments[] = + { + (char*)executable_path.pointer, + 0, + }; + Slice arg_slice = array_to_slice(arguments); + arg_slice.length -= 1; + auto execution = os_execute(arena, arg_slice, environment, {}); + auto success = execution.termination_kind == TerminationKind::exit && execution.termination_code == 0; + if (!success) + { + print(string_literal("Test failed: ")); + print(executable_path); + print(string_literal("\n")); + bb_fail(); + } + + arena_restore(arena, position); } - - arena_restore(arena, position); } } } diff --git a/src/compiler.hpp b/src/compiler.hpp index 56962e0..50836dd 100644 --- a/src/compiler.hpp +++ b/src/compiler.hpp @@ -247,6 +247,7 @@ struct Target { CPUArchitecture cpu; OperatingSystem os; + bool host_cpu_model; }; fn Target target_get_native() @@ -270,6 +271,7 @@ struct Compile String relative_file_path; BuildMode build_mode; bool has_debug_info; + bool host_cpu_model; bool silent; }; diff --git a/src/emitter.cpp b/src/emitter.cpp index 48c1448..42dd043 100644 --- a/src/emitter.cpp +++ b/src/emitter.cpp @@ -416,15 +416,23 @@ fn void llvm_initialize(Module* module) module->scope.llvm = di_compile_unit; } - char* target_triple = {}; - char* cpu_model = {}; - char* cpu_features = {}; + const char* target_triple = {}; + const char* cpu_model = {}; + const char* cpu_features = {}; if (target_compare(module->target, target_get_native())) { target_triple = llvm_global.host_triple; - cpu_model = llvm_global.host_cpu_model; - cpu_features = llvm_global.host_cpu_features; + if (module->target.host_cpu_model) + { + cpu_model = llvm_global.host_cpu_model; + cpu_features = llvm_global.host_cpu_features; + } + else + { + cpu_model = "generic"; + cpu_features = ""; + } } else {