Merge branch 'odin-lang:master' into union-tag-intrinsics

This commit is contained in:
jakubtomsu
2023-10-25 09:46:38 +02:00
committed by GitHub
4 changed files with 95 additions and 12 deletions
+32 -8
View File
@@ -21,13 +21,37 @@ when ODIN_BUILD_MODE == .Dynamic {
return 0
}
} else when !ODIN_TEST && !ODIN_NO_ENTRY_POINT {
@(link_name="main", linkage="strong", require)
main :: proc "c" (argc: i32, argv: [^]cstring) -> i32 {
args__ = argv[:argc]
context = default_context()
#force_no_inline _startup_runtime()
intrinsics.__entry_point()
#force_no_inline _cleanup_runtime()
return 0
when ODIN_NO_CRT {
// NOTE(flysand): We need to start from assembly because we need
// to retrieve argc and argv from the stack
when ODIN_ARCH == .amd64 {
@require foreign import entry "entry_unix_no_crt_amd64.asm"
} else when ODIN_ARCH == .i386 {
@require foreign import entry "entry_unix_no_crt_i386.asm"
}
@(link_name="_start_odin", linkage="strong", require)
_start_odin :: proc "c" (argc: i32, argv: [^]cstring) -> ! {
args__ = argv[:argc]
context = default_context()
#force_no_inline _startup_runtime()
intrinsics.__entry_point()
#force_no_inline _cleanup_runtime()
when ODIN_ARCH == .amd64 {
intrinsics.syscall(/*SYS_exit = */60)
} else when ODIN_ARCH == .i386 {
intrinsics.syscall(/*SYS_exit = */1)
}
unreachable()
}
} else {
@(link_name="main", linkage="strong", require)
main :: proc "c" (argc: i32, argv: [^]cstring) -> i32 {
args__ = argv[:argc]
context = default_context()
#force_no_inline _startup_runtime()
intrinsics.__entry_point()
#force_no_inline _cleanup_runtime()
return 0
}
}
}
+43
View File
@@ -0,0 +1,43 @@
bits 64
extern _start_odin
global _start
section .text
;; Entry point for programs that specify -no-crt option
;; This entry point should be compatible with dynamic loaders on linux
;; The parameters the dynamic loader passes to the _start function:
;; RDX = pointer to atexit function
;; The stack layout is as follows:
;; +-------------------+
;; NULL
;; +-------------------+
;; envp[m]
;; +-------------------+
;; ...
;; +-------------------+
;; envp[0]
;; +-------------------+
;; NULL
;; +-------------------+
;; argv[n]
;; +-------------------+
;; ...
;; +-------------------+
;; argv[0]
;; +-------------------+
;; argc
;; +-------------------+ <------ RSP
;;
_start:
;; Mark stack frame as the top of the stack
xor rbp, rbp
;; Load argc into 1st param reg, argv into 2nd param reg
pop rdi
mov rdx, rsi
;; Align stack pointer down to 16-bytes (sysv calling convention)
and rsp, -16
;; Call into odin entry point
call _start_odin
jmp $$
+18
View File
@@ -0,0 +1,18 @@
bits 32
extern _start_odin
global _start
section .text
;; NOTE(flysand): For description see the corresponding *_amd64.asm file
;; also I didn't test this on x86-32
_start:
xor ebp, rbp
pop ecx
mov eax, esp
and esp, -16
push eax
push ecx
call _start_odin
jmp $$
+2 -4
View File
@@ -63,9 +63,8 @@ class WasmMemoryInterface {
return lo + hi*4294967296;
};
loadI64(addr) {
// TODO(bill): loadI64 correctly
const lo = this.mem.getUint32(addr + 0, true);
const hi = this.mem.getUint32(addr + 4, true);
const hi = this.mem.getInt32 (addr + 4, true);
return lo + hi*4294967296;
};
loadF32(addr) { return this.mem.getFloat32(addr, true); }
@@ -95,9 +94,8 @@ class WasmMemoryInterface {
this.mem.setUint32(addr + 4, Math.floor(value / 4294967296), true);
}
storeI64(addr, value) {
// TODO(bill): storeI64 correctly
this.mem.setUint32(addr + 0, value, true);
this.mem.setUint32(addr + 4, Math.floor(value / 4294967296), true);
this.mem.setInt32 (addr + 4, Math.floor(value / 4294967296), true);
}
storeF32(addr, value) { this.mem.setFloat32(addr, value, true); }
storeF64(addr, value) { this.mem.setFloat64(addr, value, true); }