mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-02 04:38:16 +00:00
ssa - alloca all variables at the very start
This commit is contained in:
+11
-9
@@ -1,14 +1,16 @@
|
|||||||
#import "fmt.odin" as fmt
|
#import "runtime.odin" as _
|
||||||
// #import "game.odin" as game
|
#import "punity.odin" as punity
|
||||||
|
|
||||||
test_proc :: proc() {
|
|
||||||
fmt.println("Hello?")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
x := 0
|
init :: proc() {
|
||||||
// fmt.println("% % % %", "Hellope", true, 6.28, {4}int{1, 2, 3, 4})
|
|
||||||
fmt.println("%(%)", #file, #line)
|
}
|
||||||
// game.run()
|
|
||||||
|
step :: proc() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
punity.run(init, step)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -171,7 +171,7 @@ __string_ge :: proc(a, b : string) -> bool #inline { return __string_cmp(a, b) >
|
|||||||
|
|
||||||
|
|
||||||
__assert :: proc(msg: string) {
|
__assert :: proc(msg: string) {
|
||||||
os.write(os.get_standard_file(os.File_Standard.ERROR), msg as []byte)
|
_ = os.write(os.get_standard_file(os.File_Standard.ERROR), msg as []byte)
|
||||||
__debug_trap()
|
__debug_trap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+102
-54
@@ -9,18 +9,19 @@ HICON :: type HANDLE
|
|||||||
HCURSOR :: type HANDLE
|
HCURSOR :: type HANDLE
|
||||||
HMENU :: type HANDLE
|
HMENU :: type HANDLE
|
||||||
HBRUSH :: type HANDLE
|
HBRUSH :: type HANDLE
|
||||||
|
HGDIOBJ :: type HANDLE
|
||||||
WPARAM :: type uint
|
WPARAM :: type uint
|
||||||
LPARAM :: type int
|
LPARAM :: type int
|
||||||
LRESULT :: type int
|
LRESULT :: type int
|
||||||
ATOM :: type i16
|
ATOM :: type i16
|
||||||
BOOL :: type i32
|
BOOL :: type i32
|
||||||
POINT :: type struct { x, y: i32 }
|
|
||||||
WNDPROC :: type proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT
|
WNDPROC :: type proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT
|
||||||
|
|
||||||
INVALID_HANDLE_VALUE :: (-1 as int) as HANDLE
|
INVALID_HANDLE_VALUE :: (-1 as int) as HANDLE
|
||||||
|
|
||||||
CS_VREDRAW :: 1
|
CS_VREDRAW :: 0x0001
|
||||||
CS_HREDRAW :: 2
|
CS_HREDRAW :: 0x0002
|
||||||
|
CS_OWNDC :: 0x0020
|
||||||
CW_USEDEFAULT :: 0x80000000
|
CW_USEDEFAULT :: 0x80000000
|
||||||
|
|
||||||
WS_OVERLAPPED :: 0
|
WS_OVERLAPPED :: 0
|
||||||
@@ -32,13 +33,25 @@ WS_CAPTION :: 0x00C00000
|
|||||||
WS_VISIBLE :: 0x10000000
|
WS_VISIBLE :: 0x10000000
|
||||||
WS_OVERLAPPEDWINDOW :: WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX
|
WS_OVERLAPPEDWINDOW :: WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX
|
||||||
|
|
||||||
WM_DESTROY :: 0x02
|
WM_DESTROY :: 0x0002
|
||||||
WM_CLOSE :: 0x10
|
WM_CLOSE :: 0x0010
|
||||||
WM_QUIT :: 0x12
|
WM_QUIT :: 0x0012
|
||||||
|
WM_KEYDOWN :: 0x0100
|
||||||
|
WM_KEYUP :: 0x0101
|
||||||
|
|
||||||
PM_REMOVE :: 1
|
PM_REMOVE :: 1
|
||||||
|
|
||||||
COLOR_BACKGROUND :: 1 as HBRUSH
|
COLOR_BACKGROUND :: 1 as HBRUSH
|
||||||
|
BLACK_BRUSH :: 4
|
||||||
|
|
||||||
|
SM_CXSCREEN :: 0
|
||||||
|
SM_CYSCREEN :: 1
|
||||||
|
|
||||||
|
SW_SHOW :: 5
|
||||||
|
|
||||||
|
POINT :: struct #ordered {
|
||||||
|
x, y: i32
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
WNDCLASSEXA :: struct #ordered {
|
WNDCLASSEXA :: struct #ordered {
|
||||||
@@ -62,45 +75,49 @@ MSG :: struct #ordered {
|
|||||||
pt: POINT
|
pt: POINT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RECT :: struct #ordered {
|
||||||
|
left: i32
|
||||||
GetLastError :: proc() -> i32 #foreign
|
top: i32
|
||||||
ExitProcess :: proc(exit_code: u32) #foreign
|
right: i32
|
||||||
GetDesktopWindow :: proc() -> HWND #foreign
|
bottom: i32
|
||||||
GetCursorPos :: proc(p: ^POINT) -> i32 #foreign
|
|
||||||
ScreenToClient :: proc(h: HWND, p: ^POINT) -> i32 #foreign
|
|
||||||
|
|
||||||
GetModuleHandleA :: proc(module_name: ^u8) -> HINSTANCE #foreign
|
|
||||||
|
|
||||||
QueryPerformanceFrequency :: proc(result: ^i64) -> i32 #foreign
|
|
||||||
QueryPerformanceCounter :: proc(result: ^i64) -> i32 #foreign
|
|
||||||
|
|
||||||
sleep_ms :: proc(ms: i32) {
|
|
||||||
Sleep :: proc(ms: i32) -> i32 #foreign
|
|
||||||
Sleep(ms)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputDebugStringA :: proc(c_str: ^u8) #foreign
|
|
||||||
|
GetLastError :: proc() -> i32 #foreign #dll_import
|
||||||
|
ExitProcess :: proc(exit_code: u32) #foreign #dll_import
|
||||||
|
GetDesktopWindow :: proc() -> HWND #foreign #dll_import
|
||||||
|
GetCursorPos :: proc(p: ^POINT) -> i32 #foreign #dll_import
|
||||||
|
ScreenToClient :: proc(h: HWND, p: ^POINT) -> i32 #foreign #dll_import
|
||||||
|
GetModuleHandleA :: proc(module_name: ^u8) -> HINSTANCE #foreign #dll_import
|
||||||
|
GetStockObject :: proc(fn_object: i32) -> HGDIOBJ #foreign #dll_import
|
||||||
|
PostQuitMessage :: proc(exit_code: i32) #foreign #dll_import
|
||||||
|
|
||||||
|
QueryPerformanceFrequency :: proc(result: ^i64) -> i32 #foreign #dll_import
|
||||||
|
QueryPerformanceCounter :: proc(result: ^i64) -> i32 #foreign #dll_import
|
||||||
|
|
||||||
|
Sleep :: proc(ms: i32) -> i32 #foreign
|
||||||
|
|
||||||
|
OutputDebugStringA :: proc(c_str: ^u8) #foreign #dll_import
|
||||||
|
|
||||||
|
|
||||||
RegisterClassExA :: proc(wc: ^WNDCLASSEXA) -> ATOM #foreign
|
RegisterClassExA :: proc(wc: ^WNDCLASSEXA) -> ATOM #foreign #dll_import
|
||||||
CreateWindowExA :: proc(ex_style: u32,
|
CreateWindowExA :: proc(ex_style: u32,
|
||||||
class_name, title: ^u8,
|
class_name, title: ^u8,
|
||||||
style: u32,
|
style: u32,
|
||||||
x, y: u32,
|
x, y, w, h: i32,
|
||||||
w, h: i32,
|
|
||||||
parent: HWND, menu: HMENU, instance: HINSTANCE,
|
parent: HWND, menu: HMENU, instance: HINSTANCE,
|
||||||
param: rawptr) -> HWND #foreign
|
param: rawptr) -> HWND #foreign #dll_import
|
||||||
|
|
||||||
ShowWindow :: proc(hwnd: HWND, cmd_show: i32) -> BOOL #foreign
|
ShowWindow :: proc(hwnd: HWND, cmd_show: i32) -> BOOL #foreign #dll_import
|
||||||
TranslateMessage :: proc(msg: ^MSG) -> BOOL #foreign
|
TranslateMessage :: proc(msg: ^MSG) -> BOOL #foreign #dll_import
|
||||||
DispatchMessageA :: proc(msg: ^MSG) -> LRESULT #foreign
|
DispatchMessageA :: proc(msg: ^MSG) -> LRESULT #foreign #dll_import
|
||||||
UpdateWindow :: proc(hwnd: HWND) -> BOOL #foreign
|
UpdateWindow :: proc(hwnd: HWND) -> BOOL #foreign #dll_import
|
||||||
PeekMessageA :: proc(msg: ^MSG, hwnd: HWND,
|
PeekMessageA :: proc(msg: ^MSG, hwnd: HWND,
|
||||||
msg_filter_min, msg_filter_max, remove_msg: u32) -> BOOL #foreign
|
msg_filter_min, msg_filter_max, remove_msg: u32) -> BOOL #foreign #dll_import
|
||||||
|
|
||||||
DefWindowProcA :: proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT #foreign
|
DefWindowProcA :: proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT #foreign #dll_import
|
||||||
|
|
||||||
|
AdjustWindowRect :: proc(rect: ^RECT, style: u32, menu: BOOL) -> BOOL #foreign #dll_import
|
||||||
|
|
||||||
|
|
||||||
GetQueryPerformanceFrequency :: proc() -> i64 {
|
GetQueryPerformanceFrequency :: proc() -> i64 {
|
||||||
@@ -109,21 +126,21 @@ GetQueryPerformanceFrequency :: proc() -> i64 {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
GetCommandLineA :: proc() -> ^u8 #foreign
|
GetCommandLineA :: proc() -> ^u8 #foreign #dll_import
|
||||||
|
GetSystemMetrics :: proc(index: i32) -> i32 #foreign #dll_import
|
||||||
GetCurrentThreadId :: proc() -> u32 #foreign
|
GetCurrentThreadId :: proc() -> u32 #foreign #dll_import
|
||||||
|
|
||||||
// File Stuff
|
// File Stuff
|
||||||
|
|
||||||
CloseHandle :: proc(h: HANDLE) -> i32 #foreign
|
CloseHandle :: proc(h: HANDLE) -> i32 #foreign #dll_import
|
||||||
GetStdHandle :: proc(h: i32) -> HANDLE #foreign
|
GetStdHandle :: proc(h: i32) -> HANDLE #foreign #dll_import
|
||||||
CreateFileA :: proc(filename: ^u8, desired_access, share_mode: u32,
|
CreateFileA :: proc(filename: ^u8, desired_access, share_mode: u32,
|
||||||
security: rawptr,
|
security: rawptr,
|
||||||
creation, flags_and_attribs: u32, template_file: HANDLE) -> HANDLE #foreign
|
creation, flags_and_attribs: u32, template_file: HANDLE) -> HANDLE #foreign #dll_import
|
||||||
ReadFile :: proc(h: HANDLE, buf: rawptr, to_read: u32, bytes_read: ^i32, overlapped: rawptr) -> BOOL #foreign
|
ReadFile :: proc(h: HANDLE, buf: rawptr, to_read: u32, bytes_read: ^i32, overlapped: rawptr) -> BOOL #foreign #dll_import
|
||||||
WriteFile :: proc(h: HANDLE, buf: rawptr, len: i32, written_result: ^i32, overlapped: rawptr) -> i32 #foreign
|
WriteFile :: proc(h: HANDLE, buf: rawptr, len: i32, written_result: ^i32, overlapped: rawptr) -> i32 #foreign #dll_import
|
||||||
|
|
||||||
GetFileSizeEx :: proc(file_handle: HANDLE, file_size: ^i64) -> BOOL #foreign
|
GetFileSizeEx :: proc(file_handle: HANDLE, file_size: ^i64) -> BOOL #foreign #dll_import
|
||||||
|
|
||||||
FILE_SHARE_READ :: 0x00000001
|
FILE_SHARE_READ :: 0x00000001
|
||||||
FILE_SHARE_WRITE :: 0x00000002
|
FILE_SHARE_WRITE :: 0x00000002
|
||||||
@@ -144,17 +161,48 @@ OPEN_ALWAYS :: 4
|
|||||||
TRUNCATE_EXISTING :: 5
|
TRUNCATE_EXISTING :: 5
|
||||||
|
|
||||||
|
|
||||||
HeapAlloc :: proc(h: HANDLE, flags: u32, bytes: int) -> rawptr #foreign
|
HeapAlloc :: proc(h: HANDLE, flags: u32, bytes: int) -> rawptr #foreign #dll_import
|
||||||
HeapFree :: proc(h: HANDLE, flags: u32, memory: rawptr) -> BOOL #foreign
|
HeapFree :: proc(h: HANDLE, flags: u32, memory: rawptr) -> BOOL #foreign #dll_import
|
||||||
GetProcessHeap :: proc() -> HANDLE #foreign
|
GetProcessHeap :: proc() -> HANDLE #foreign #dll_import
|
||||||
|
|
||||||
|
|
||||||
HEAP_ZERO_MEMORY :: 0x00000008
|
HEAP_ZERO_MEMORY :: 0x00000008
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// GDI
|
||||||
|
|
||||||
|
BITMAPINFO :: struct #ordered {
|
||||||
|
HEADER :: struct #ordered {
|
||||||
|
size: u32
|
||||||
|
width, height: i32
|
||||||
|
planes, bit_count: i16
|
||||||
|
compression: u32
|
||||||
|
size_image: u32
|
||||||
|
x_pels_per_meter: i32
|
||||||
|
y_pels_per_meter: i32
|
||||||
|
clr_used: u32
|
||||||
|
clr_important: u32
|
||||||
|
}
|
||||||
|
using header: HEADER
|
||||||
|
colors: [1]RGBQUAD
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RGBQUAD :: struct #ordered {
|
||||||
|
blue, green, red, reserved: byte
|
||||||
|
}
|
||||||
|
|
||||||
|
BI_RGB :: 0
|
||||||
|
DIB_RGB_COLORS :: 0x00
|
||||||
|
SRCCOPY : u32 : 0x00cc0020
|
||||||
|
|
||||||
|
StretchDIBits :: proc(hdc: HDC,
|
||||||
|
x_dst, y_dst, width_dst, height_dst: i32,
|
||||||
|
x_src, y_src, width_src, header_src: i32,
|
||||||
|
bits: rawptr, bits_info: ^BITMAPINFO,
|
||||||
|
usage: u32,
|
||||||
|
rop: u32) -> i32 #foreign #dll_import
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -222,24 +270,24 @@ PIXELFORMATDESCRIPTOR :: struct #ordered {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GetDC :: proc(h: HANDLE) -> HDC #foreign
|
GetDC :: proc(h: HANDLE) -> HDC #foreign
|
||||||
SetPixelFormat :: proc(hdc: HDC, pixel_format: i32, pfd: ^PIXELFORMATDESCRIPTOR ) -> BOOL #foreign
|
SetPixelFormat :: proc(hdc: HDC, pixel_format: i32, pfd: ^PIXELFORMATDESCRIPTOR ) -> BOOL #foreign #dll_import
|
||||||
ChoosePixelFormat :: proc(hdc: HDC, pfd: ^PIXELFORMATDESCRIPTOR) -> i32 #foreign
|
ChoosePixelFormat :: proc(hdc: HDC, pfd: ^PIXELFORMATDESCRIPTOR) -> i32 #foreign #dll_import
|
||||||
SwapBuffers :: proc(hdc: HDC) -> BOOL #foreign
|
SwapBuffers :: proc(hdc: HDC) -> BOOL #foreign #dll_import
|
||||||
|
ReleaseDC :: proc(wnd: HWND, hdc: HDC) -> i32 #foreign #dll_import
|
||||||
|
|
||||||
WGL_CONTEXT_MAJOR_VERSION_ARB :: 0x2091
|
WGL_CONTEXT_MAJOR_VERSION_ARB :: 0x2091
|
||||||
WGL_CONTEXT_MINOR_VERSION_ARB :: 0x2092
|
WGL_CONTEXT_MINOR_VERSION_ARB :: 0x2092
|
||||||
WGL_CONTEXT_PROFILE_MASK_ARB :: 0x9126
|
WGL_CONTEXT_PROFILE_MASK_ARB :: 0x9126
|
||||||
WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :: 0x0002
|
WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :: 0x0002
|
||||||
|
|
||||||
wglCreateContext :: proc(hdc: HDC) -> HGLRC #foreign
|
wglCreateContext :: proc(hdc: HDC) -> HGLRC #foreign #dll_import
|
||||||
wglMakeCurrent :: proc(hdc: HDC, hglrc: HGLRC) -> BOOL #foreign
|
wglMakeCurrent :: proc(hdc: HDC, hglrc: HGLRC) -> BOOL #foreign #dll_import
|
||||||
wglGetProcAddress :: proc(c_str: ^u8) -> PROC #foreign
|
wglGetProcAddress :: proc(c_str: ^u8) -> PROC #foreign #dll_import
|
||||||
wglDeleteContext :: proc(hglrc: HGLRC) -> BOOL #foreign
|
wglDeleteContext :: proc(hglrc: HGLRC) -> BOOL #foreign #dll_import
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GetAsyncKeyState :: proc(v_key: i32) -> i16 #foreign
|
GetAsyncKeyState :: proc(v_key: i32) -> i16 #foreign #dll_import
|
||||||
|
|
||||||
is_key_down :: proc(key: Key_Code) -> bool {
|
is_key_down :: proc(key: Key_Code) -> bool {
|
||||||
return GetAsyncKeyState(key as i32) < 0
|
return GetAsyncKeyState(key as i32) < 0
|
||||||
|
|||||||
@@ -754,12 +754,14 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
|
|||||||
case Addressing_Type:
|
case Addressing_Type:
|
||||||
error(&c->error_collector, ast_node_token(node), "Is not an expression");
|
error(&c->error_collector, ast_node_token(node), "Is not an expression");
|
||||||
break;
|
break;
|
||||||
default:
|
case Addressing_NoValue:
|
||||||
if (kind == Expr_Stmt) {
|
return;
|
||||||
return;
|
default: {
|
||||||
}
|
gbString expr_str = expr_to_string(operand.expr);
|
||||||
error(&c->error_collector, ast_node_token(node), "Expression is not used");
|
defer (gb_string_free(expr_str));
|
||||||
break;
|
|
||||||
|
error(&c->error_collector, ast_node_token(node), "Expression is not used: `%s`", expr_str);
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
|
|||||||
@@ -387,13 +387,22 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
|
|||||||
ssa_fprintf(f, "%%%d = alloca ", value->id);
|
ssa_fprintf(f, "%%%d = alloca ", value->id);
|
||||||
ssa_print_type(f, m->sizes, type);
|
ssa_print_type(f, m->sizes, type);
|
||||||
ssa_fprintf(f, ", align %lld\n", type_align_of(m->sizes, m->allocator, type));
|
ssa_fprintf(f, ", align %lld\n", type_align_of(m->sizes, m->allocator, type));
|
||||||
if (instr->Local.zero_initialized) {
|
// if (instr->Local.zero_initialized) {
|
||||||
ssa_fprintf(f, "\tstore ");
|
// ssa_fprintf(f, "\tstore ");
|
||||||
ssa_print_type(f, m->sizes, type);
|
// ssa_print_type(f, m->sizes, type);
|
||||||
ssa_fprintf(f, " zeroinitializer, ");
|
// ssa_fprintf(f, " zeroinitializer, ");
|
||||||
ssa_print_type(f, m->sizes, type);
|
// ssa_print_type(f, m->sizes, type);
|
||||||
ssa_fprintf(f, "* %%%d\n", value->id);
|
// ssa_fprintf(f, "* %%%d\n", value->id);
|
||||||
}
|
// }
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ssaInstr_ZeroInit: {
|
||||||
|
Type *type = type_deref(ssa_type(instr->ZeroInit.address));
|
||||||
|
ssa_fprintf(f, "\tstore ");
|
||||||
|
ssa_print_type(f, m->sizes, type);
|
||||||
|
ssa_fprintf(f, " zeroinitializer, ");
|
||||||
|
ssa_print_type(f, m->sizes, type);
|
||||||
|
ssa_fprintf(f, "* %%%d\n", instr->ZeroInit.address->id);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case ssaInstr_Store: {
|
case ssaInstr_Store: {
|
||||||
@@ -745,10 +754,23 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
|
|||||||
void ssa_print_proc(ssaFileBuffer *f, ssaModule *m, ssaProcedure *proc) {
|
void ssa_print_proc(ssaFileBuffer *f, ssaModule *m, ssaProcedure *proc) {
|
||||||
if (proc->body == NULL) {
|
if (proc->body == NULL) {
|
||||||
ssa_fprintf(f, "declare ");
|
ssa_fprintf(f, "declare ");
|
||||||
|
if (proc->tags & ProcTag_dll_import) {
|
||||||
|
ssa_fprintf(f, "dllimport ");
|
||||||
|
}
|
||||||
|
if (proc->tags & ProcTag_dll_export) {
|
||||||
|
ssa_fprintf(f, "dllexport ");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ssa_fprintf(f, "\ndefine ");
|
ssa_fprintf(f, "\ndefine ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (proc->tags & ProcTag_stdcall) {
|
||||||
|
ssa_fprintf(f, "cc 64 ");
|
||||||
|
}
|
||||||
|
if (proc->tags & ProcTag_fastcall) {
|
||||||
|
ssa_fprintf(f, "cc 65 ");
|
||||||
|
}
|
||||||
|
|
||||||
auto *proc_type = &proc->type->Proc;
|
auto *proc_type = &proc->type->Proc;
|
||||||
|
|
||||||
if (proc_type->result_count == 0) {
|
if (proc_type->result_count == 0) {
|
||||||
@@ -773,7 +795,9 @@ void ssa_print_proc(ssaFileBuffer *f, ssaModule *m, ssaProcedure *proc) {
|
|||||||
ssa_fprintf(f, ", ");
|
ssa_fprintf(f, ", ");
|
||||||
}
|
}
|
||||||
ssa_print_type(f, m->sizes, e->type);
|
ssa_print_type(f, m->sizes, e->type);
|
||||||
ssa_fprintf(f, " %%%.*s", LIT(e->token.string));
|
if (proc->body != NULL) {
|
||||||
|
ssa_fprintf(f, " %%%.*s", LIT(e->token.string));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -787,14 +811,20 @@ void ssa_print_proc(ssaFileBuffer *f, ssaModule *m, ssaProcedure *proc) {
|
|||||||
ssa_fprintf(f, "noinline ");
|
ssa_fprintf(f, "noinline ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if (proc->tags & ProcTag_stdcall) {
|
||||||
|
// ssa_fprintf(f, "\"cc\"=\"64\" ");
|
||||||
|
// }
|
||||||
|
// if (proc->tags & ProcTag_fastcall) {
|
||||||
|
// ssa_fprintf(f, "\"cc\"=\"65\" ");
|
||||||
|
// }
|
||||||
|
|
||||||
if (proc->tags & ProcTag_foreign) {
|
if (proc->tags & ProcTag_foreign) {
|
||||||
// TODO(bill): Set calling convention
|
|
||||||
ssa_fprintf(f, "; foreign\n");
|
ssa_fprintf(f, "; foreign\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proc->body != NULL) {
|
if (proc->body != NULL) {
|
||||||
|
// ssa_fprintf(f, "nounwind uwtable {\n");
|
||||||
ssa_fprintf(f, "{\n");
|
ssa_fprintf(f, "{\n");
|
||||||
gb_for_array(i, proc->blocks) {
|
gb_for_array(i, proc->blocks) {
|
||||||
ssaBlock *block = proc->blocks[i];
|
ssaBlock *block = proc->blocks[i];
|
||||||
|
|||||||
+39
-7
@@ -65,6 +65,8 @@ struct ssaProcedure {
|
|||||||
isize scope_index;
|
isize scope_index;
|
||||||
gbArray(ssaDefer) defer_stmts;
|
gbArray(ssaDefer) defer_stmts;
|
||||||
gbArray(ssaBlock *) blocks;
|
gbArray(ssaBlock *) blocks;
|
||||||
|
ssaBlock * decl_block;
|
||||||
|
ssaBlock * entry_block;
|
||||||
ssaBlock * curr_block;
|
ssaBlock * curr_block;
|
||||||
ssaTargetList * target_list;
|
ssaTargetList * target_list;
|
||||||
};
|
};
|
||||||
@@ -78,6 +80,7 @@ struct ssaProcedure {
|
|||||||
SSA_INSTR_KIND(Invalid), \
|
SSA_INSTR_KIND(Invalid), \
|
||||||
SSA_INSTR_KIND(Comment), \
|
SSA_INSTR_KIND(Comment), \
|
||||||
SSA_INSTR_KIND(Local), \
|
SSA_INSTR_KIND(Local), \
|
||||||
|
SSA_INSTR_KIND(ZeroInit), \
|
||||||
SSA_INSTR_KIND(Store), \
|
SSA_INSTR_KIND(Store), \
|
||||||
SSA_INSTR_KIND(Load), \
|
SSA_INSTR_KIND(Load), \
|
||||||
SSA_INSTR_KIND(GetElementPtr), \
|
SSA_INSTR_KIND(GetElementPtr), \
|
||||||
@@ -151,6 +154,9 @@ struct ssaInstr {
|
|||||||
Type * type;
|
Type * type;
|
||||||
b32 zero_initialized;
|
b32 zero_initialized;
|
||||||
} Local;
|
} Local;
|
||||||
|
struct {
|
||||||
|
ssaValue *address;
|
||||||
|
} ZeroInit;
|
||||||
struct {
|
struct {
|
||||||
ssaValue *address;
|
ssaValue *address;
|
||||||
ssaValue *value;
|
ssaValue *value;
|
||||||
@@ -509,6 +515,13 @@ ssaValue *ssa_make_instr_store(ssaProcedure *p, ssaValue *address, ssaValue *val
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssaValue *ssa_make_instr_zero_init(ssaProcedure *p, ssaValue *address) {
|
||||||
|
ssaValue *v = ssa_alloc_instr(p, ssaInstr_ZeroInit);
|
||||||
|
ssaInstr *i = &v->Instr;
|
||||||
|
i->ZeroInit.address = address;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
ssaValue *ssa_make_instr_load(ssaProcedure *p, ssaValue *address) {
|
ssaValue *ssa_make_instr_load(ssaProcedure *p, ssaValue *address) {
|
||||||
ssaValue *v = ssa_alloc_instr(p, ssaInstr_Load);
|
ssaValue *v = ssa_alloc_instr(p, ssaInstr_Load);
|
||||||
ssaInstr *i = &v->Instr;
|
ssaInstr *i = &v->Instr;
|
||||||
@@ -743,13 +756,26 @@ ssaValue *ssa_emit_select(ssaProcedure *p, ssaValue *cond, ssaValue *t, ssaValue
|
|||||||
return ssa_emit(p, ssa_make_instr_select(p, cond, t, f));
|
return ssa_emit(p, ssa_make_instr_select(p, cond, t, f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssaValue *ssa_emit_zero_init(ssaProcedure *p, ssaValue *address) {
|
||||||
|
return ssa_emit(p, ssa_make_instr_zero_init(p, address));
|
||||||
|
}
|
||||||
|
|
||||||
ssaValue *ssa_emit_comment(ssaProcedure *p, String text) {
|
ssaValue *ssa_emit_comment(ssaProcedure *p, String text) {
|
||||||
return ssa_emit(p, ssa_make_instr_comment(p, text));
|
return ssa_emit(p, ssa_make_instr_comment(p, text));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ssaValue *ssa_add_local(ssaProcedure *proc, Entity *e, b32 zero_initialized = true) {
|
ssaValue *ssa_add_local(ssaProcedure *proc, Entity *e, b32 zero_initialized = true) {
|
||||||
return ssa_emit(proc, ssa_make_instr_local(proc, e, zero_initialized));
|
ssaBlock *b = proc->decl_block; // all variables must be in the first block
|
||||||
|
ssaValue *instr = ssa_make_instr_local(proc, e, zero_initialized);
|
||||||
|
instr->Instr.parent = b;
|
||||||
|
gb_array_append(b->instrs, instr);
|
||||||
|
|
||||||
|
if (zero_initialized) {
|
||||||
|
ssa_emit_zero_init(proc, instr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return instr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssaValue *ssa_add_local_for_identifier(ssaProcedure *proc, AstNode *name, b32 zero_initialized) {
|
ssaValue *ssa_add_local_for_identifier(ssaProcedure *proc, AstNode *name, b32 zero_initialized) {
|
||||||
@@ -769,11 +795,11 @@ ssaValue *ssa_add_local_generated(ssaProcedure *proc, Type *type) {
|
|||||||
if (proc->curr_block) {
|
if (proc->curr_block) {
|
||||||
scope = proc->curr_block->scope;
|
scope = proc->curr_block->scope;
|
||||||
}
|
}
|
||||||
Entity *entity = make_entity_variable(proc->module->allocator,
|
Entity *e = make_entity_variable(proc->module->allocator,
|
||||||
scope,
|
scope,
|
||||||
empty_token,
|
empty_token,
|
||||||
type);
|
type);
|
||||||
return ssa_emit(proc, ssa_make_instr_local(proc, entity, true));
|
return ssa_add_local(proc, e, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssaValue *ssa_add_param(ssaProcedure *proc, Entity *e) {
|
ssaValue *ssa_add_param(ssaProcedure *proc, Entity *e) {
|
||||||
@@ -944,7 +970,9 @@ ssaValue *ssa_lvalue_load(ssaProcedure *proc, ssaAddr lval) {
|
|||||||
void ssa_begin_procedure_body(ssaProcedure *proc) {
|
void ssa_begin_procedure_body(ssaProcedure *proc) {
|
||||||
gb_array_init(proc->blocks, gb_heap_allocator());
|
gb_array_init(proc->blocks, gb_heap_allocator());
|
||||||
gb_array_init(proc->defer_stmts, gb_heap_allocator());
|
gb_array_init(proc->defer_stmts, gb_heap_allocator());
|
||||||
proc->curr_block = ssa_add_block(proc, proc->type_expr, make_string("entry"));
|
proc->decl_block = ssa_add_block(proc, proc->type_expr, make_string("decls"));
|
||||||
|
proc->entry_block = ssa_add_block(proc, proc->type_expr, make_string("entry"));
|
||||||
|
proc->curr_block = proc->entry_block;
|
||||||
|
|
||||||
if (proc->type->Proc.params != NULL) {
|
if (proc->type->Proc.params != NULL) {
|
||||||
auto *params = &proc->type->Proc.params->Tuple;
|
auto *params = &proc->type->Proc.params->Tuple;
|
||||||
@@ -960,6 +988,9 @@ void ssa_end_procedure_body(ssaProcedure *proc) {
|
|||||||
ssa_emit_ret(proc, NULL);
|
ssa_emit_ret(proc, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc->curr_block = proc->decl_block;
|
||||||
|
ssa_emit_jump(proc, proc->entry_block);
|
||||||
|
|
||||||
|
|
||||||
// Number blocks and registers
|
// Number blocks and registers
|
||||||
i32 reg_id = 0;
|
i32 reg_id = 0;
|
||||||
@@ -973,6 +1004,7 @@ void ssa_end_procedure_body(ssaProcedure *proc) {
|
|||||||
// NOTE(bill): Ignore non-returning instructions
|
// NOTE(bill): Ignore non-returning instructions
|
||||||
switch (instr->kind) {
|
switch (instr->kind) {
|
||||||
case ssaInstr_Comment:
|
case ssaInstr_Comment:
|
||||||
|
case ssaInstr_ZeroInit:
|
||||||
case ssaInstr_Store:
|
case ssaInstr_Store:
|
||||||
case ssaInstr_Br:
|
case ssaInstr_Br:
|
||||||
case ssaInstr_Ret:
|
case ssaInstr_Ret:
|
||||||
|
|||||||
+6
-5
@@ -128,10 +128,10 @@ int main(int argc, char **argv) {
|
|||||||
exit_code = win32_exec_command_line_app(
|
exit_code = win32_exec_command_line_app(
|
||||||
// "../misc/llvm-bin/opt %s -o %.*s.bc "
|
// "../misc/llvm-bin/opt %s -o %.*s.bc "
|
||||||
"opt %s -o %.*s.bc "
|
"opt %s -o %.*s.bc "
|
||||||
"-memcpyopt "
|
// "-memcpyopt "
|
||||||
"-mem2reg "
|
// "-mem2reg "
|
||||||
"-die -dse "
|
// "-die -dse "
|
||||||
"-dce "
|
// "-dce "
|
||||||
// "-S "
|
// "-S "
|
||||||
// "-debug-pass=Arguments "
|
// "-debug-pass=Arguments "
|
||||||
"",
|
"",
|
||||||
@@ -148,13 +148,14 @@ int main(int argc, char **argv) {
|
|||||||
gb_for_array(i, parser.system_libraries) {
|
gb_for_array(i, parser.system_libraries) {
|
||||||
String lib = parser.system_libraries[i];
|
String lib = parser.system_libraries[i];
|
||||||
isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
|
isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
|
||||||
" -l%.*s.lib", LIT(lib));
|
" -l%.*s", LIT(lib));
|
||||||
lib_str = gb_string_appendc(lib_str, lib_str_buf);
|
lib_str = gb_string_appendc(lib_str, lib_str_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
exit_code = win32_exec_command_line_app(
|
exit_code = win32_exec_command_line_app(
|
||||||
"clang %.*s.bc -o %.*s.exe "
|
"clang %.*s.bc -o %.*s.exe "
|
||||||
"-O0 "
|
"-O0 "
|
||||||
|
// "-O2 "
|
||||||
"-Wno-override-module "
|
"-Wno-override-module "
|
||||||
"%s",
|
"%s",
|
||||||
cast(int)base_name_len, output_name,
|
cast(int)base_name_len, output_name,
|
||||||
|
|||||||
+34
-16
@@ -65,12 +65,19 @@ enum DeclKind {
|
|||||||
Declaration_Count,
|
Declaration_Count,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ProcTag {
|
enum ProcTag : u64 {
|
||||||
ProcTag_bounds_check = GB_BIT(0),
|
ProcTag_bounds_check = GB_BIT(0),
|
||||||
ProcTag_no_bounds_check = GB_BIT(1),
|
ProcTag_no_bounds_check = GB_BIT(1),
|
||||||
ProcTag_foreign = GB_BIT(2),
|
|
||||||
ProcTag_inline = GB_BIT(3),
|
ProcTag_foreign = GB_BIT(10),
|
||||||
ProcTag_no_inline = GB_BIT(4),
|
ProcTag_inline = GB_BIT(11),
|
||||||
|
ProcTag_no_inline = GB_BIT(12),
|
||||||
|
ProcTag_dll_import = GB_BIT(13),
|
||||||
|
ProcTag_dll_export = GB_BIT(14),
|
||||||
|
|
||||||
|
ProcTag_stdcall = GB_BIT(15),
|
||||||
|
ProcTag_fastcall = GB_BIT(16),
|
||||||
|
// ProcTag_cdecl = GB_BIT(17),
|
||||||
};
|
};
|
||||||
|
|
||||||
enum VarDeclTag {
|
enum VarDeclTag {
|
||||||
@@ -220,7 +227,7 @@ AST_NODE_KIND(_DeclBegin, "", struct{}) \
|
|||||||
AST_NODE_KIND(BadDecl, "bad declaration", struct { Token begin, end; }) \
|
AST_NODE_KIND(BadDecl, "bad declaration", struct { Token begin, end; }) \
|
||||||
AST_NODE_KIND(VarDecl, "variable declaration", struct { \
|
AST_NODE_KIND(VarDecl, "variable declaration", struct { \
|
||||||
DeclKind kind; \
|
DeclKind kind; \
|
||||||
u32 tags; \
|
u64 tags; \
|
||||||
b32 is_using; \
|
b32 is_using; \
|
||||||
AstNodeArray names; \
|
AstNodeArray names; \
|
||||||
AstNode *type; \
|
AstNode *type; \
|
||||||
@@ -1171,10 +1178,19 @@ b32 is_foreign_name_valid(String name) {
|
|||||||
|
|
||||||
void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name) {
|
void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name) {
|
||||||
// TODO(bill): Add this to procedure literals too
|
// TODO(bill): Add this to procedure literals too
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
while (f->cursor[0].kind == Token_Hash) {
|
while (f->cursor[0].kind == Token_Hash) {
|
||||||
AstNode *tag_expr = parse_tag_expr(f, NULL);
|
AstNode *tag_expr = parse_tag_expr(f, NULL);
|
||||||
ast_node(te, TagExpr, tag_expr);
|
ast_node(te, TagExpr, tag_expr);
|
||||||
String tag_name = te->name.string;
|
String tag_name = te->name.string;
|
||||||
|
|
||||||
|
#define ELSE_IF_ADD_TAG(name) \
|
||||||
|
else if (are_strings_equal(tag_name, make_string(#name))) { \
|
||||||
|
check_proc_add_tag(f, tag_expr, tags, ProcTag_##name, tag_name); \
|
||||||
|
}
|
||||||
|
|
||||||
if (are_strings_equal(tag_name, make_string("foreign"))) {
|
if (are_strings_equal(tag_name, make_string("foreign"))) {
|
||||||
check_proc_add_tag(f, tag_expr, tags, ProcTag_foreign, tag_name);
|
check_proc_add_tag(f, tag_expr, tags, ProcTag_foreign, tag_name);
|
||||||
if (f->cursor[0].kind == Token_String) {
|
if (f->cursor[0].kind == Token_String) {
|
||||||
@@ -1186,19 +1202,21 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name) {
|
|||||||
|
|
||||||
next_token(f);
|
next_token(f);
|
||||||
}
|
}
|
||||||
} else if (are_strings_equal(tag_name, make_string("bounds_check"))) {
|
}
|
||||||
check_proc_add_tag(f, tag_expr, tags, ProcTag_bounds_check, tag_name);
|
ELSE_IF_ADD_TAG(bounds_check)
|
||||||
} else if (are_strings_equal(tag_name, make_string("no_bounds_check"))) {
|
ELSE_IF_ADD_TAG(no_bounds_check)
|
||||||
check_proc_add_tag(f, tag_expr, tags, ProcTag_no_bounds_check, tag_name);
|
ELSE_IF_ADD_TAG(inline)
|
||||||
} else if (are_strings_equal(tag_name, make_string("inline"))) {
|
ELSE_IF_ADD_TAG(no_inline)
|
||||||
check_proc_add_tag(f, tag_expr, tags, ProcTag_inline, tag_name);
|
ELSE_IF_ADD_TAG(dll_import)
|
||||||
} else if (are_strings_equal(tag_name, make_string("no_inline"))) {
|
ELSE_IF_ADD_TAG(dll_export)
|
||||||
check_proc_add_tag(f, tag_expr, tags, ProcTag_no_inline, tag_name);
|
ELSE_IF_ADD_TAG(stdcall)
|
||||||
// } else if (are_strings_equal(tag_name, make_string("no_context"))) {
|
ELSE_IF_ADD_TAG(fastcall)
|
||||||
// check_proc_add_tag(f, tag_expr, tags, ProcTag_no_context, tag_name);
|
// ELSE_IF_ADD_TAG(cdecl)
|
||||||
} else {
|
else {
|
||||||
ast_file_err(f, ast_node_token(tag_expr), "Unknown procedure tag");
|
ast_file_err(f, ast_node_token(tag_expr), "Unknown procedure tag");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef ELSE_IF_ADD_TAG
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*tags & ProcTag_inline) && (*tags & ProcTag_no_inline)) {
|
if ((*tags & ProcTag_inline) && (*tags & ProcTag_no_inline)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user