Browse Source

Begin work on windows 386

gingerBill 5 years ago
parent
commit
0ea64182f1

+ 4 - 4
core/os/os_windows.odin

@@ -196,12 +196,12 @@ file_size :: proc(fd: Handle) -> (i64, Errno) {
 
 
 
 
 // NOTE(bill): Uses startup to initialize it
 // NOTE(bill): Uses startup to initialize it
-stdin  := get_std_handle(int(win32.STD_INPUT_HANDLE));
-stdout := get_std_handle(int(win32.STD_OUTPUT_HANDLE));
-stderr := get_std_handle(int(win32.STD_ERROR_HANDLE));
+stdin  := get_std_handle(uint(win32.STD_INPUT_HANDLE));
+stdout := get_std_handle(uint(win32.STD_OUTPUT_HANDLE));
+stderr := get_std_handle(uint(win32.STD_ERROR_HANDLE));
 
 
 
 
-get_std_handle :: proc "contextless" (h: int) -> Handle {
+get_std_handle :: proc "contextless" (h: uint) -> Handle {
 	fd := win32.GetStdHandle(win32.DWORD(h));
 	fd := win32.GetStdHandle(win32.DWORD(h));
 	win32.SetHandleInformation(fd, win32.HANDLE_FLAG_INHERIT, 0);
 	win32.SetHandleInformation(fd, win32.HANDLE_FLAG_INHERIT, 0);
 	return Handle(fd);
 	return Handle(fd);

+ 4 - 4
core/runtime/core.odin

@@ -1126,21 +1126,21 @@ card :: proc(s: $S/bit_set[$E; $U]) -> int {
 
 
 
 
 @builtin
 @builtin
-raw_array_data :: proc(a: $P/^($T/[$N]$E)) -> ^E {
+raw_array_data :: proc "contextless" (a: $P/^($T/[$N]$E)) -> ^E {
 	return (^E)(a);
 	return (^E)(a);
 }
 }
 @builtin
 @builtin
-raw_slice_data :: proc(s: $S/[]$E) -> ^E {
+raw_slice_data :: proc "contextless" (s: $S/[]$E) -> ^E {
 	ptr := (transmute(Raw_Slice)s).data;
 	ptr := (transmute(Raw_Slice)s).data;
 	return (^E)(ptr);
 	return (^E)(ptr);
 }
 }
 @builtin
 @builtin
-raw_dynamic_array_data :: proc(s: $S/[dynamic]$E) -> ^E {
+raw_dynamic_array_data :: proc "contextless" (s: $S/[dynamic]$E) -> ^E {
 	ptr := (transmute(Raw_Dynamic_Array)s).data;
 	ptr := (transmute(Raw_Dynamic_Array)s).data;
 	return (^E)(ptr);
 	return (^E)(ptr);
 }
 }
 @builtin
 @builtin
-raw_string_data :: proc(s: $S/string) -> ^u8 {
+raw_string_data :: proc "contextless" (s: $S/string) -> ^u8 {
 	return (transmute(Raw_String)s).data;
 	return (transmute(Raw_String)s).data;
 }
 }
 
 

+ 49 - 16
core/runtime/procs_windows_386.odin

@@ -2,35 +2,68 @@ package runtime
 
 
 foreign import kernel32 "system:Kernel32.lib"
 foreign import kernel32 "system:Kernel32.lib"
 
 
-@private
-@(link_name="_tls_index")
-_tls_index: u32;
+windows_trap_array_bounds :: proc "contextless" () -> ! {
+	DWORD :: u32;
+	ULONG_PTR :: uint;
 
 
-@private
-@(link_name="_fltused")
-_fltused: i32 = 0x9875;
+	EXCEPTION_ARRAY_BOUNDS_EXCEEDED :: 0xC000008C;
 
 
-@(link_name="memcpy")
-memcpy :: proc "c" (dst, src: rawptr, len: int) -> rawptr {
 	foreign kernel32 {
 	foreign kernel32 {
-		RtlCopyMemory :: proc "c" (dst, src: rawptr, len: int) ---
+		RaiseException :: proc "stdcall" (dwExceptionCode, dwExceptionFlags, nNumberOfArguments: DWORD, lpArguments: ^ULONG_PTR) -> ! ---
 	}
 	}
-	if dst == nil || src == nil || len == 0 {
+
+	RaiseException(EXCEPTION_ARRAY_BOUNDS_EXCEEDED, 0, 0, nil);
+}
+
+windows_trap_type_assertion :: proc "contextless" () -> ! {
+	windows_trap_array_bounds();
+}
+
+@(private, require, link_name="_fltused") _fltused: i32 = 0x9875;
+
+@(private, require, link_name="_tls_index") _tls_index: u32;
+@(private, require, link_name="_tls_array") _tls_array: u32;
+
+
+
+@(link_name="memcpy")
+memcpy :: proc "c" (dst, src: rawptr, len: int) -> rawptr {
+	if dst == nil || src == nil || len == 0 || dst == src {
 		return dst;
 		return dst;
 	}
 	}
-	RtlCopyMemory(dst, src, len);
+	d := uintptr(dst);
+	s := uintptr(src);
+	n := uintptr(len);
+
+	for i in 0..<n {
+		(^byte)(d+i)^ = (^byte)(s+i)^;
+	}
+
 	return dst;
 	return dst;
 }
 }
 
 
 @(link_name="memmove")
 @(link_name="memmove")
 memmove :: proc "c" (dst, src: rawptr, len: int) -> rawptr {
 memmove :: proc "c" (dst, src: rawptr, len: int) -> rawptr {
-	foreign kernel32 {
-		RtlMoveMemory :: proc "c" (dst, src: rawptr, len: int) ---
-	}
-	if dst == nil || src == nil || len == 0 {
+	if dst == nil || src == nil || len == 0 || dst == src {
 		return dst;
 		return dst;
 	}
 	}
-	RtlMoveMemory(dst, src, len);
+
+	d := uintptr(dst);
+	s := uintptr(src);
+	n := uintptr(len);
+
+	if s < d && d < s+n {
+		// Overlap
+		for i := n-1; n >= 0; i -= 1 {
+			(^byte)(d+i)^ = (^byte)(s+i)^;
+		}
+
+	} else {
+		for i in 0..<n {
+			(^byte)(d+i)^ = (^byte)(s+i)^;
+		}
+	}
+
 	return dst;
 	return dst;
 }
 }
 
 

+ 1 - 1
core/runtime/procs_windows_amd64.odin

@@ -9,7 +9,7 @@ windows_trap_array_bounds :: proc "contextless" () -> ! {
 	EXCEPTION_ARRAY_BOUNDS_EXCEEDED :: 0xC000008C;
 	EXCEPTION_ARRAY_BOUNDS_EXCEEDED :: 0xC000008C;
 
 
 	foreign kernel32 {
 	foreign kernel32 {
-		RaiseException :: proc(dwExceptionCode, dwExceptionFlags, nNumberOfArguments: DWORD, lpArguments: ^ULONG_PTR) -> ! ---
+		RaiseException :: proc "stdcall" (dwExceptionCode, dwExceptionFlags, nNumberOfArguments: DWORD, lpArguments: ^ULONG_PTR) -> ! ---
 	}
 	}
 
 
 	RaiseException(EXCEPTION_ARRAY_BOUNDS_EXCEEDED, 0, 0, nil);
 	RaiseException(EXCEPTION_ARRAY_BOUNDS_EXCEEDED, 0, 0, nil);

+ 3 - 1
src/build_settings.cpp

@@ -138,6 +138,7 @@ struct BuildContext {
 	bool   use_lld;
 	bool   use_lld;
 	bool   vet;
 	bool   vet;
 	bool   cross_compiling;
 	bool   cross_compiling;
+	bool   different_os;
 	bool   keep_object_files;
 	bool   keep_object_files;
 
 
 	bool   use_llvm_api;
 	bool   use_llvm_api;
@@ -624,8 +625,9 @@ void init_build_context(TargetMetrics *cross_target) {
 	#endif
 	#endif
 
 
 	if (cross_target != nullptr && metrics != cross_target) {
 	if (cross_target != nullptr && metrics != cross_target) {
-		metrics = cross_target;
+		bc->different_os = cross_target->os != metrics->os;
 		bc->cross_compiling = true;
 		bc->cross_compiling = true;
+		metrics = cross_target;
 	}
 	}
 
 
 	GB_ASSERT(metrics->os != TargetOs_Invalid);
 	GB_ASSERT(metrics->os != TargetOs_Invalid);

+ 15 - 5
src/llvm_backend.cpp

@@ -12272,19 +12272,29 @@ void lb_generate_code(lbGenerator *gen) {
 	}
 	}
 
 
 	if (!(build_context.build_mode == BuildMode_DynamicLibrary && !has_dll_main)) {
 	if (!(build_context.build_mode == BuildMode_DynamicLibrary && !has_dll_main)) {
+
+
 		Type *params  = alloc_type_tuple();
 		Type *params  = alloc_type_tuple();
 		Type *results = alloc_type_tuple();
 		Type *results = alloc_type_tuple();
 
 
-		array_init(&params->Tuple.variables, heap_allocator(), 2);
-		params->Tuple.variables[0] = alloc_entity_param(nullptr, make_token_ident("argc"), t_i32, false, true);
-		params->Tuple.variables[1] = alloc_entity_param(nullptr, make_token_ident("argv"), alloc_type_pointer(t_cstring), false, true);
+		String name = str_lit("main");
+		if (build_context.metrics.os == TargetOs_windows && build_context.metrics.arch == TargetArch_386) {
+			name = str_lit("mainCRTStartup");
+		} else {
+			array_init(&params->Tuple.variables, heap_allocator(), 2);
+			params->Tuple.variables[0] = alloc_entity_param(nullptr, make_token_ident("argc"), t_i32, false, true);
+			params->Tuple.variables[1] = alloc_entity_param(nullptr, make_token_ident("argv"), alloc_type_pointer(t_cstring), false, true);
+		}
 
 
 		array_init(&results->Tuple.variables, heap_allocator(), 1);
 		array_init(&results->Tuple.variables, heap_allocator(), 1);
 		results->Tuple.variables[0] = alloc_entity_param(nullptr, make_token_ident("_"),   t_i32, false, true);
 		results->Tuple.variables[0] = alloc_entity_param(nullptr, make_token_ident("_"),   t_i32, false, true);
 
 
-		Type *proc_type = alloc_type_proc(nullptr, params, 2, results, 1, false, ProcCC_CDecl);
+		Type *proc_type = alloc_type_proc(nullptr,
+			params, params->Tuple.variables.count,
+			results, results->Tuple.variables.count, false, ProcCC_CDecl);
+
 
 
-		lbProcedure *p = lb_create_dummy_procedure(m, str_lit("main"), proc_type);
+		lbProcedure *p = lb_create_dummy_procedure(m, name, proc_type);
 		p->is_startup = true;
 		p->is_startup = true;
 
 
 		lb_begin_procedure_body(p);
 		lb_begin_procedure_body(p);

+ 6 - 6
src/main.cpp

@@ -162,7 +162,7 @@ i32 linker_stage(lbGenerator *gen) {
 			LIT(target_arch_names[build_context.metrics.arch])
 			LIT(target_arch_names[build_context.metrics.arch])
 		);
 		);
 #endif
 #endif
-	} else if (build_context.cross_compiling) {
+	} else if (build_context.cross_compiling && build_context.different_os) {
 		gb_printf_err("Linking for cross compilation for this platform is not yet supported (%.*s %.*s)\n",
 		gb_printf_err("Linking for cross compilation for this platform is not yet supported (%.*s %.*s)\n",
 			LIT(target_os_names[build_context.metrics.os]),
 			LIT(target_os_names[build_context.metrics.os]),
 			LIT(target_arch_names[build_context.metrics.arch])
 			LIT(target_arch_names[build_context.metrics.arch])
@@ -1689,10 +1689,10 @@ int main(int arg_count, char const **arg_ptr) {
 
 
 
 
 	init_build_context(selected_target_metrics ? selected_target_metrics->metrics : nullptr);
 	init_build_context(selected_target_metrics ? selected_target_metrics->metrics : nullptr);
-	if (build_context.word_size == 4 && build_context.metrics.os != TargetOs_js) {
-		print_usage_line(0, "%.*s 32-bit is not yet supported for this platform", LIT(args[0]));
-		return 1;
-	}
+	// if (build_context.word_size == 4 && build_context.metrics.os != TargetOs_js) {
+	// 	print_usage_line(0, "%.*s 32-bit is not yet supported for this platform", LIT(args[0]));
+	// 	return 1;
+	// }
 	if (build_context.metrics.os == TargetOs_js) {
 	if (build_context.metrics.os == TargetOs_js) {
 		if (!build_context.use_llvm_api) {
 		if (!build_context.use_llvm_api) {
 			print_usage_line(0, "%.*s - js platform only supported with the -llvm-api backend", LIT(args[0]));
 			print_usage_line(0, "%.*s - js platform only supported with the -llvm-api backend", LIT(args[0]));
@@ -1880,7 +1880,7 @@ int main(int arg_count, char const **arg_ptr) {
 				LIT(target_arch_names[build_context.metrics.arch])
 				LIT(target_arch_names[build_context.metrics.arch])
 			);
 			);
 	#endif
 	#endif
-		} else if (build_context.cross_compiling) {
+		} else if (build_context.cross_compiling && build_context.different_os) {
 			gb_printf_err("Linking for cross compilation for this platform is not yet supported (%.*s %.*s)\n",
 			gb_printf_err("Linking for cross compilation for this platform is not yet supported (%.*s %.*s)\n",
 				LIT(target_os_names[build_context.metrics.os]),
 				LIT(target_os_names[build_context.metrics.os]),
 				LIT(target_arch_names[build_context.metrics.arch])
 				LIT(target_arch_names[build_context.metrics.arch])