Merge pull request #1332 from odin-lang/nasm-support

NASM Support
This commit is contained in:
gingerBill
2021-11-26 23:06:33 +00:00
committed by GitHub
8 changed files with 128 additions and 27 deletions

29
bin/nasm/windows/LICENSE Normal file
View File

@@ -0,0 +1,29 @@
NASM is now licensed under the 2-clause BSD license, also known as the
simplified BSD license.
Copyright 1996-2010 the NASM Authors - All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

BIN
bin/nasm/windows/nasm.exe Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,13 @@
global __chkstk
global _tls_index
global _fltused
section .data
_tls_index: dd 0
_fltused: dd 0x9875
section .text
__chkstk: ; proc "c" (rawptr)
; TODO implement correctly
ret

View File

@@ -20,13 +20,6 @@ windows_trap_type_assertion :: proc "contextless" () -> ! {
}
when ODIN_NO_CRT {
@(private, export, link_name="_tls_index")
_tls_index: u32
@(private, export, link_name="_fltused")
_fltused: i32 = 0x9875
@(private, export, link_name="__chkstk")
__chkstk :: proc "c" (rawptr) {
}
@(require)
foreign import crt_lib "procs_windows_amd64.asm"
}

View File

@@ -196,6 +196,7 @@ struct BuildContext {
bool has_resource;
String link_flags;
String extra_linker_flags;
String extra_assembler_flags;
String microarch;
BuildModeKind build_mode;
bool generate_docs;
@@ -821,6 +822,18 @@ bool show_error_line(void) {
return build_context.show_error_line;
}
bool has_asm_extension(String const &path) {
String ext = path_extension(path);
if (ext == ".asm") {
return true;
} else if (ext == ".s") {
return true;
} else if (ext == ".S") {
return true;
}
return false;
}
void init_build_context(TargetMetrics *cross_target) {
BuildContext *bc = &build_context;

View File

@@ -4120,6 +4120,14 @@ void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) {
mpmc_enqueue(&ctx->info->required_foreign_imports_through_force_queue, e);
add_entity_use(ctx, nullptr, e);
}
if (has_asm_extension(fullpath)) {
if (build_context.metrics.arch != TargetArch_amd64 ||
build_context.metrics.os != TargetOs_windows) {
error(decl, "Assembly files are not yet supported on this platform: %.*s_%.*s",
LIT(target_os_names[build_context.metrics.os]), LIT(target_arch_names[build_context.metrics.arch]));
}
}
}
// Returns true if a new package is present

View File

@@ -177,7 +177,6 @@ i32 linker_stage(lbGenerator *gen) {
gbString lib_str = gb_string_make(heap_allocator(), "");
defer (gb_string_free(lib_str));
char lib_str_buf[1024] = {0};
char const *output_ext = "exe";
gbString link_settings = gb_string_make_reserve(heap_allocator(), 256);
@@ -212,28 +211,43 @@ i32 linker_stage(lbGenerator *gen) {
add_path(find_result.windows_sdk_ucrt_library_path);
add_path(find_result.vs_library_path);
}
StringSet libs = {};
string_set_init(&libs, heap_allocator(), 64);
defer (string_set_destroy(&libs));
StringSet asm_files = {};
string_set_init(&asm_files, heap_allocator(), 64);
defer (string_set_destroy(&asm_files));
for_array(j, gen->modules.entries) {
lbModule *m = gen->modules.entries[j].value;
for_array(i, m->foreign_library_paths) {
String lib = m->foreign_library_paths[i];
GB_ASSERT(lib.len < gb_count_of(lib_str_buf)-1);
gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
" \"%.*s\"", LIT(lib));
lib_str = gb_string_appendc(lib_str, lib_str_buf);
if (has_asm_extension(lib)) {
string_set_add(&asm_files, lib);
} else {
string_set_add(&libs, lib);
}
}
}
for_array(i, gen->default_module.foreign_library_paths) {
String lib = gen->default_module.foreign_library_paths[i];
GB_ASSERT(lib.len < gb_count_of(lib_str_buf)-1);
gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
" \"%.*s\"", LIT(lib));
lib_str = gb_string_appendc(lib_str, lib_str_buf);
if (has_asm_extension(lib)) {
string_set_add(&asm_files, lib);
} else {
string_set_add(&libs, lib);
}
}
for_array(i, libs.entries) {
String lib = libs.entries[i].value;
lib_str = gb_string_append_fmt(lib_str, " \"%.*s\"", LIT(lib));
}
if (build_context.build_mode == BuildMode_DynamicLibrary) {
output_ext = "dll";
link_settings = gb_string_append_fmt(link_settings, " /DLL");
@@ -254,6 +268,27 @@ i32 linker_stage(lbGenerator *gen) {
if (build_context.ODIN_DEBUG) {
link_settings = gb_string_append_fmt(link_settings, " /DEBUG");
}
for_array(i, asm_files.entries) {
String asm_file = asm_files.entries[i].value;
String obj_file = concatenate_strings(permanent_allocator(), asm_file, str_lit(".obj"));
result = system_exec_command_line_app("nasm",
"\"%.*s\\bin\\nasm\\windows\\nasm.exe\" \"%.*s\" "
"-f win64 "
"-o \"%.*s\" "
"%.*s "
"",
LIT(build_context.ODIN_ROOT), LIT(asm_file),
LIT(obj_file),
LIT(build_context.extra_assembler_flags)
);
if (result) {
return result;
}
array_add(&gen->output_object_paths, obj_file);
}
gbString object_files = gb_string_make(heap_allocator(), "");
defer (gb_string_free(object_files));
@@ -325,10 +360,10 @@ i32 linker_stage(lbGenerator *gen) {
LIT(build_context.extra_linker_flags),
lib_str
);
if (result) {
if (result) {
return result;
}
}
}
#else
timings_start_section(timings, str_lit("ld-link"));
@@ -617,6 +652,7 @@ enum BuildFlagKind {
BuildFlag_UseLLVMApi,
BuildFlag_IgnoreUnknownAttributes,
BuildFlag_ExtraLinkerFlags,
BuildFlag_ExtraAssemblerFlags,
BuildFlag_Microarch,
BuildFlag_TestName,
@@ -768,7 +804,8 @@ bool parse_build_flags(Array<String> args) {
add_flag(&build_flags, BuildFlag_VetExtra, str_lit("vet-extra"), BuildFlagParam_None, Command__does_check);
add_flag(&build_flags, BuildFlag_UseLLVMApi, str_lit("llvm-api"), BuildFlagParam_None, Command__does_build);
add_flag(&build_flags, BuildFlag_IgnoreUnknownAttributes, str_lit("ignore-unknown-attributes"), BuildFlagParam_None, Command__does_check);
add_flag(&build_flags, BuildFlag_ExtraLinkerFlags, str_lit("extra-linker-flags"), BuildFlagParam_String, Command__does_build);
add_flag(&build_flags, BuildFlag_ExtraLinkerFlags, str_lit("extra-linker-flags"), BuildFlagParam_String, Command__does_build);
add_flag(&build_flags, BuildFlag_ExtraAssemblerFlags, str_lit("extra-assembler-flags"), BuildFlagParam_String, Command__does_build);
add_flag(&build_flags, BuildFlag_Microarch, str_lit("microarch"), BuildFlagParam_String, Command__does_build);
add_flag(&build_flags, BuildFlag_TestName, str_lit("test-name"), BuildFlagParam_String, Command_test);
@@ -1314,11 +1351,14 @@ bool parse_build_flags(Array<String> args) {
case BuildFlag_IgnoreUnknownAttributes:
build_context.ignore_unknown_attributes = true;
break;
case BuildFlag_ExtraLinkerFlags: {
case BuildFlag_ExtraLinkerFlags:
GB_ASSERT(value.kind == ExactValue_String);
build_context.extra_linker_flags = value.value_string;
break;
}
case BuildFlag_ExtraAssemblerFlags:
GB_ASSERT(value.kind == ExactValue_String);
build_context.extra_assembler_flags = value.value_string;
break;
case BuildFlag_Microarch: {
GB_ASSERT(value.kind == ExactValue_String);
build_context.microarch = value.value_string;
@@ -2031,6 +2071,11 @@ void print_show_help(String const arg0, String const &command) {
print_usage_line(1, "-extra-linker-flags:<string>");
print_usage_line(2, "Adds extra linker specific flags in a string");
print_usage_line(0, "");
print_usage_line(1, "-extra-assembler-flags:<string>");
print_usage_line(2, "Adds extra assembler specific flags in a string");
print_usage_line(0, "");
print_usage_line(1, "-microarch:<string>");
print_usage_line(2, "Specifies the specific micro-architecture for the build in a string");