mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-10 06:53:03 +00:00
Update TB; Fix calling nullptr TB_Node* problems
This commit is contained in:
@@ -439,7 +439,7 @@ struct TB_Node {
|
||||
typedef struct { // TB_BRANCH
|
||||
// avoid empty structs with flexible members
|
||||
int64_t _;
|
||||
int64_t keys[/* input_count - 1 */];
|
||||
int64_t keys[];
|
||||
} TB_NodeBranch;
|
||||
|
||||
typedef struct { // TB_PROJ
|
||||
@@ -538,19 +538,6 @@ typedef struct {
|
||||
TB_Node* value;
|
||||
} TB_SwitchEntry;
|
||||
|
||||
typedef struct TB_Loop {
|
||||
// refers to another entry in TB_LoopInfo... unless it's -1
|
||||
ptrdiff_t parent_loop;
|
||||
|
||||
TB_Node* header;
|
||||
TB_Node* backedge;
|
||||
} TB_Loop;
|
||||
|
||||
typedef struct TB_LoopInfo {
|
||||
size_t count;
|
||||
TB_Loop* loops;
|
||||
} TB_LoopInfo;
|
||||
|
||||
typedef enum {
|
||||
TB_EXECUTABLE_UNKNOWN,
|
||||
TB_EXECUTABLE_PE,
|
||||
@@ -648,7 +635,7 @@ TB_API void tb_module_destroy(TB_Module* m);
|
||||
// When targetting windows & thread local storage, you'll need to bind a tls index
|
||||
// which is usually just a global that the runtime support has initialized, if you
|
||||
// dont and the tls_index is used, it'll crash
|
||||
TB_API void tb_module_set_tls_index(TB_Module* m, const char* name);
|
||||
TB_API void tb_module_set_tls_index(TB_Module* m, ptrdiff_t len, const char* name);
|
||||
|
||||
// You don't need to manually call this unless you want to resolve locations before
|
||||
// exporting.
|
||||
@@ -756,7 +743,7 @@ TB_API TB_External* tb_next_external(TB_External* e);
|
||||
TB_API TB_ExternalType tb_extern_get_type(TB_External* e);
|
||||
TB_Global* tb_extern_transmute(TB_External* e, TB_DebugType* dbg_type, TB_Linkage linkage);
|
||||
|
||||
TB_API TB_External* tb_extern_create(TB_Module* m, const char* name, TB_ExternalType type);
|
||||
TB_API TB_External* tb_extern_create(TB_Module* m, ptrdiff_t len, const char* name, TB_ExternalType type);
|
||||
TB_API TB_FileID tb_file_create(TB_Module* m, const char* path);
|
||||
|
||||
// Called once you're done with TB operations on a thread (or i guess when it's
|
||||
@@ -798,7 +785,7 @@ TB_API TB_FunctionPrototype* tb_prototype_create(TB_Module* m, TB_CallingConv cc
|
||||
////////////////////////////////
|
||||
// Globals
|
||||
////////////////////////////////
|
||||
TB_API TB_Global* tb_global_create(TB_Module* m, const char* name, TB_DebugType* dbg_type, TB_Linkage linkage);
|
||||
TB_API TB_Global* tb_global_create(TB_Module* m, ptrdiff_t len, const char* name, TB_DebugType* dbg_type, TB_Linkage linkage);
|
||||
|
||||
// allocate space for the global
|
||||
TB_API void tb_global_set_storage(TB_Module* m, TB_ModuleSection* section, TB_Global* global, size_t size, size_t align, size_t max_objects);
|
||||
@@ -818,8 +805,11 @@ TB_API TB_ModuleSection* tb_module_get_tls(TB_Module* m);
|
||||
////////////////////////////////
|
||||
// Function Attributes
|
||||
////////////////////////////////
|
||||
TB_API void tb_node_append_attrib(TB_Node* n, TB_Attrib* a);
|
||||
|
||||
// These are parts of a function that describe metadata for instructions
|
||||
TB_API void tb_function_attrib_variable(TB_Function* f, TB_Node* n, const char* name, TB_DebugType* type);
|
||||
TB_API TB_Attrib* tb_function_attrib_variable(TB_Function* f, ptrdiff_t len, const char* name, TB_DebugType* type);
|
||||
TB_API TB_Attrib* tb_function_attrib_scope(TB_Function* f, TB_Attrib* parent_scope);
|
||||
|
||||
////////////////////////////////
|
||||
// Debug info Generation
|
||||
@@ -830,9 +820,9 @@ TB_API TB_DebugType* tb_debug_get_integer(TB_Module* m, bool is_signed, int bits
|
||||
TB_API TB_DebugType* tb_debug_get_float(TB_Module* m, TB_FloatFormat fmt);
|
||||
TB_API TB_DebugType* tb_debug_create_ptr(TB_Module* m, TB_DebugType* base);
|
||||
TB_API TB_DebugType* tb_debug_create_array(TB_Module* m, TB_DebugType* base, size_t count);
|
||||
TB_API TB_DebugType* tb_debug_create_struct(TB_Module* m, const char* tag);
|
||||
TB_API TB_DebugType* tb_debug_create_union(TB_Module* m, const char* tag);
|
||||
TB_API TB_DebugType* tb_debug_create_field(TB_Module* m, TB_DebugType* type, const char* name, TB_CharUnits offset);
|
||||
TB_API TB_DebugType* tb_debug_create_struct(TB_Module* m, ptrdiff_t len, const char* tag);
|
||||
TB_API TB_DebugType* tb_debug_create_union(TB_Module* m, ptrdiff_t len, const char* tag);
|
||||
TB_API TB_DebugType* tb_debug_create_field(TB_Module* m, TB_DebugType* type, ptrdiff_t len, const char* name, TB_CharUnits offset);
|
||||
TB_API void tb_debug_complete_record(TB_DebugType* type, TB_DebugType** members, size_t count, TB_CharUnits size, TB_CharUnits align);
|
||||
|
||||
////////////////////////////////
|
||||
@@ -869,12 +859,14 @@ TB_API void tb_inst_set_location(TB_Function* f, TB_FileID file, int line);
|
||||
TB_API TB_DataType tb_vector_type(TB_DataTypeEnum type, int width);
|
||||
|
||||
// if section is NULL, default to .text
|
||||
TB_API TB_Function* tb_function_create(TB_Module* m, const char* name, TB_Linkage linkage, TB_ComdatType comdat);
|
||||
TB_API TB_Function* tb_function_create(TB_Module* m, ptrdiff_t len, const char* name, TB_Linkage linkage, TB_ComdatType comdat);
|
||||
|
||||
TB_API void* tb_function_get_jit_pos(TB_Function* f);
|
||||
|
||||
// if len is -1, it's null terminated
|
||||
TB_API void tb_symbol_set_name(TB_Symbol* s, ptrdiff_t len, const char* name);
|
||||
|
||||
TB_API void tb_symbol_bind_ptr(TB_Symbol* s, void* ptr);
|
||||
TB_API void tb_symbol_set_name(TB_Symbol* s, const char* name);
|
||||
TB_API const char* tb_symbol_get_name(TB_Symbol* s);
|
||||
|
||||
// if arena is NULL, defaults to module arena which is freed on tb_free_thread_resources
|
||||
@@ -915,7 +907,6 @@ TB_API TB_Node* tb_inst_load(TB_Function* f, TB_DataType dt, TB_Node* addr, TB_C
|
||||
TB_API void tb_inst_store(TB_Function* f, TB_DataType dt, TB_Node* addr, TB_Node* val, TB_CharUnits align, bool is_volatile);
|
||||
|
||||
TB_API TB_Node* tb_inst_bool(TB_Function* f, bool imm);
|
||||
TB_API TB_Node* tb_inst_ptr(TB_Function* f, uint64_t imm);
|
||||
TB_API TB_Node* tb_inst_sint(TB_Function* f, TB_DataType dt, int64_t imm);
|
||||
TB_API TB_Node* tb_inst_uint(TB_Function* f, TB_DataType dt, uint64_t imm);
|
||||
TB_API TB_Node* tb_inst_float32(TB_Function* f, float imm);
|
||||
@@ -923,9 +914,12 @@ TB_API TB_Node* tb_inst_float64(TB_Function* f, double imm);
|
||||
TB_API TB_Node* tb_inst_cstring(TB_Function* f, const char* str);
|
||||
TB_API TB_Node* tb_inst_string(TB_Function* f, size_t len, const char* str);
|
||||
|
||||
// Broadcasts 'val' across 'count' elements starting 'dst'
|
||||
// write 'val' over 'count' bytes on 'dst'
|
||||
TB_API void tb_inst_memset(TB_Function* f, TB_Node* dst, TB_Node* val, TB_Node* count, TB_CharUnits align, bool is_volatile);
|
||||
|
||||
// zero 'count' bytes on 'dst'
|
||||
TB_API void tb_inst_memzero(TB_Function* f, TB_Node* dst, TB_Node* val, TB_Node* count, TB_CharUnits align, bool is_volatile);
|
||||
|
||||
// performs a copy of 'count' elements from one memory location to another
|
||||
// both locations cannot overlap.
|
||||
TB_API void tb_inst_memcpy(TB_Function* f, TB_Node* dst, TB_Node* src, TB_Node* count, TB_CharUnits align, bool is_volatile);
|
||||
@@ -1052,13 +1046,15 @@ TB_API TB_FuncOpt* tb_funcopt_enter(TB_Function* f, TB_Arena* arena);
|
||||
TB_API void tb_funcopt_exit(TB_FuncOpt* opt);
|
||||
|
||||
TB_API bool tb_funcopt_peephole(TB_FuncOpt* opt);
|
||||
TB_API bool tb_funcopt_mem2reg(TB_FuncOpt* f);
|
||||
TB_API bool tb_funcopt_loop(TB_FuncOpt* f);
|
||||
TB_API bool tb_funcopt_mem2reg(TB_FuncOpt* opt);
|
||||
TB_API bool tb_funcopt_loop(TB_FuncOpt* opt);
|
||||
|
||||
TB_API void tb_funcopt_kill(TB_FuncOpt* restrict queue, TB_Node* n);
|
||||
// isn't an optimization, just does the name flat form of IR printing
|
||||
TB_API bool tb_funcopt_print(TB_FuncOpt* opt);
|
||||
|
||||
TB_API bool tb_funcopt_mark(TB_FuncOpt* restrict queue, TB_Node* n);
|
||||
TB_API void tb_funcopt_mark_users(TB_FuncOpt* restrict queue, TB_Node* n);
|
||||
TB_API void tb_funcopt_kill(TB_FuncOpt* opt, TB_Node* n);
|
||||
TB_API bool tb_funcopt_mark(TB_FuncOpt* opt, TB_Node* n);
|
||||
TB_API void tb_funcopt_mark_users(TB_FuncOpt* opt, TB_Node* n);
|
||||
|
||||
////////////////////////////////
|
||||
// IR access
|
||||
|
||||
BIN
src/tilde/tb.lib
BIN
src/tilde/tb.lib
Binary file not shown.
@@ -184,7 +184,7 @@ gb_internal void cg_create_global_variables(cgModule *m) {
|
||||
// gb_printf_err("max_type_info_count: %td\n", max_type_info_count);
|
||||
Type *t = alloc_type_array(t_type_info, max_type_info_count);
|
||||
|
||||
TB_Global *g = tb_global_create(m->mod, CG_TYPE_INFO_DATA_NAME, nullptr, TB_LINKAGE_PRIVATE);
|
||||
TB_Global *g = tb_global_create(m->mod, -1, CG_TYPE_INFO_DATA_NAME, nullptr, TB_LINKAGE_PRIVATE);
|
||||
tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), g, type_size_of(t), 16, max_type_info_count);
|
||||
|
||||
cgValue value = cg_value(g, alloc_type_pointer(t));
|
||||
@@ -219,7 +219,7 @@ gb_internal void cg_create_global_variables(cgModule *m) {
|
||||
{
|
||||
char const *name = CG_TYPE_INFO_TYPES_NAME;
|
||||
Type *t = alloc_type_array(t_type_info_ptr, count);
|
||||
TB_Global *g = tb_global_create(m->mod, name, nullptr, TB_LINKAGE_PRIVATE);
|
||||
TB_Global *g = tb_global_create(m->mod, -1, name, nullptr, TB_LINKAGE_PRIVATE);
|
||||
tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), g, type_size_of(t), 16, count);
|
||||
cg_global_type_info_member_types = cg_addr(cg_value(g, alloc_type_pointer(t)));
|
||||
|
||||
@@ -227,14 +227,14 @@ gb_internal void cg_create_global_variables(cgModule *m) {
|
||||
{
|
||||
char const *name = CG_TYPE_INFO_NAMES_NAME;
|
||||
Type *t = alloc_type_array(t_string, count);
|
||||
TB_Global *g = tb_global_create(m->mod, name, nullptr, TB_LINKAGE_PRIVATE);
|
||||
TB_Global *g = tb_global_create(m->mod, -1, name, nullptr, TB_LINKAGE_PRIVATE);
|
||||
tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), g, type_size_of(t), 16, count);
|
||||
cg_global_type_info_member_names = cg_addr(cg_value(g, alloc_type_pointer(t)));
|
||||
}
|
||||
{
|
||||
char const *name = CG_TYPE_INFO_OFFSETS_NAME;
|
||||
Type *t = alloc_type_array(t_uintptr, count);
|
||||
TB_Global *g = tb_global_create(m->mod, name, nullptr, TB_LINKAGE_PRIVATE);
|
||||
TB_Global *g = tb_global_create(m->mod, -1, name, nullptr, TB_LINKAGE_PRIVATE);
|
||||
tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), g, type_size_of(t), 16, count);
|
||||
cg_global_type_info_member_offsets = cg_addr(cg_value(g, alloc_type_pointer(t)));
|
||||
}
|
||||
@@ -242,7 +242,7 @@ gb_internal void cg_create_global_variables(cgModule *m) {
|
||||
{
|
||||
char const *name = CG_TYPE_INFO_USINGS_NAME;
|
||||
Type *t = alloc_type_array(t_bool, count);
|
||||
TB_Global *g = tb_global_create(m->mod, name, nullptr, TB_LINKAGE_PRIVATE);
|
||||
TB_Global *g = tb_global_create(m->mod, -1, name, nullptr, TB_LINKAGE_PRIVATE);
|
||||
tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), g, type_size_of(t), 16, count);
|
||||
cg_global_type_info_member_usings = cg_addr(cg_value(g, alloc_type_pointer(t)));
|
||||
}
|
||||
@@ -250,7 +250,7 @@ gb_internal void cg_create_global_variables(cgModule *m) {
|
||||
{
|
||||
char const *name = CG_TYPE_INFO_TAGS_NAME;
|
||||
Type *t = alloc_type_array(t_string, count);
|
||||
TB_Global *g = tb_global_create(m->mod, name, nullptr, TB_LINKAGE_PRIVATE);
|
||||
TB_Global *g = tb_global_create(m->mod, -1, name, nullptr, TB_LINKAGE_PRIVATE);
|
||||
tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), g, type_size_of(t), 16, count);
|
||||
cg_global_type_info_member_tags = cg_addr(cg_value(g, alloc_type_pointer(t)));
|
||||
}
|
||||
@@ -268,7 +268,7 @@ cgModule *cg_module_create(Checker *c) {
|
||||
TB_FeatureSet feature_set = {};
|
||||
bool is_jit = false;
|
||||
m->mod = tb_module_create(TB_ARCH_X86_64, TB_SYSTEM_WINDOWS, &feature_set, is_jit);
|
||||
tb_module_set_tls_index(m->mod, "_tls_index");
|
||||
tb_module_set_tls_index(m->mod, 10, "_tls_index");
|
||||
|
||||
map_init(&m->values);
|
||||
array_init(&m->procedures_to_generate, heap_allocator());
|
||||
@@ -634,8 +634,6 @@ gb_internal cgProcedure *cg_procedure_create(cgModule *m, Entity *entity, bool i
|
||||
// p->scope_stack.allocator = a;
|
||||
// map_init(&p->tuple_fix_map, 0);
|
||||
|
||||
char const *link_name_c = alloc_cstring(temporary_allocator(), link_name);
|
||||
|
||||
TB_Linkage linkage = TB_LINKAGE_PRIVATE;
|
||||
if (p->is_export) {
|
||||
linkage = TB_LINKAGE_PUBLIC;
|
||||
@@ -643,11 +641,11 @@ gb_internal cgProcedure *cg_procedure_create(cgModule *m, Entity *entity, bool i
|
||||
if (ignore_body) {
|
||||
linkage = TB_LINKAGE_PUBLIC;
|
||||
}
|
||||
p->symbol = cast(TB_Symbol *)tb_extern_create(m->mod, link_name_c, TB_EXTERNAL_SO_LOCAL);
|
||||
p->symbol = cast(TB_Symbol *)tb_extern_create(m->mod, link_name.len, cast(char const *)link_name.text, TB_EXTERNAL_SO_LOCAL);
|
||||
}
|
||||
|
||||
if (p->symbol == nullptr) {
|
||||
p->func = tb_function_create(m->mod, link_name_c, linkage, TB_COMDAT_NONE);
|
||||
p->func = tb_function_create(m->mod, link_name.len, cast(char const *)link_name.text, linkage, TB_COMDAT_NONE);
|
||||
tb_function_set_prototype(p->func, cg_procedure_type_as_prototype(m, p->type), tb_default_arena());
|
||||
p->symbol = cast(TB_Symbol *)p->func;
|
||||
}
|
||||
@@ -688,12 +686,9 @@ gb_internal cgProcedure *cg_procedure_create_dummy(cgModule *m, String const &li
|
||||
// map_init(&p->tuple_fix_map, 0);
|
||||
|
||||
|
||||
|
||||
char const *link_name_c = alloc_cstring(temporary_allocator(), link_name);
|
||||
|
||||
TB_Linkage linkage = TB_LINKAGE_PRIVATE;
|
||||
|
||||
p->func = tb_function_create(m->mod, link_name_c, linkage, TB_COMDAT_NONE);
|
||||
p->func = tb_function_create(m->mod, link_name.len, cast(char const *)link_name.text, linkage, TB_COMDAT_NONE);
|
||||
tb_function_set_prototype(p->func, cg_procedure_type_as_prototype(m, p->type), tb_default_arena());
|
||||
p->symbol = cast(TB_Symbol *)p->func;
|
||||
|
||||
@@ -715,6 +710,13 @@ gb_internal void cg_procedure_end(cgProcedure *p) {
|
||||
return;
|
||||
}
|
||||
tb_inst_ret(p->func, 0, nullptr);
|
||||
if (p->name == "main") {
|
||||
TB_Arena *arena = tb_default_arena();
|
||||
defer (arena->free(arena));
|
||||
TB_FuncOpt *opt = tb_funcopt_enter(p->func, arena);
|
||||
defer (tb_funcopt_exit(opt));
|
||||
tb_funcopt_print(opt);
|
||||
}
|
||||
tb_module_compile_function(p->module->mod, p->func, TB_ISEL_FAST);
|
||||
}
|
||||
|
||||
|
||||
@@ -212,4 +212,6 @@ gb_internal void cg_emit_store(cgProcedure *p, cgValue dst, cgValue const &src,
|
||||
|
||||
gb_internal cgAddr cg_add_local(cgProcedure *p, Type *type, Entity *e, bool zero_init);
|
||||
|
||||
gb_internal cgValue cg_build_call_expr(cgProcedure *p, Ast *expr);
|
||||
gb_internal cgValue cg_build_call_expr(cgProcedure *p, Ast *expr);
|
||||
|
||||
gb_internal cgValue cg_find_procedure_value_from_entity(cgModule *m, Entity *e);
|
||||
@@ -8,7 +8,7 @@ gb_internal cgValue cg_const_nil(cgProcedure *p, Type *type) {
|
||||
TB_Module *m = p->module->mod;
|
||||
char name[32] = {};
|
||||
gb_snprintf(name, 31, "cnil$%u", 1+p->module->const_nil_guid.fetch_add(1));
|
||||
TB_Global *global = tb_global_create(m, name, nullptr, TB_LINKAGE_PRIVATE);
|
||||
TB_Global *global = tb_global_create(m, -1, name, nullptr, TB_LINKAGE_PRIVATE);
|
||||
tb_global_set_storage(m, tb_module_get_rdata(m), global, size, align, 0);
|
||||
|
||||
TB_Symbol *symbol = cast(TB_Symbol *)global;
|
||||
@@ -41,6 +41,18 @@ gb_internal cgValue cg_const_value(cgModule *m, cgProcedure *p, Type *type, Exac
|
||||
return cg_const_nil(p, type);
|
||||
}
|
||||
|
||||
if (value.kind == ExactValue_Procedure) {
|
||||
Ast *expr = unparen_expr(value.value_procedure);
|
||||
Entity *e = entity_of_node(expr);
|
||||
if (e != nullptr) {
|
||||
cgValue found = cg_find_procedure_value_from_entity(m, e);
|
||||
GB_ASSERT(are_types_identical(type, found.type));
|
||||
return found;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GB_ASSERT(node != nullptr);
|
||||
return cg_value(node, type);
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ gb_internal cgValue cg_build_expr(cgProcedure *p, Ast *expr) {
|
||||
|
||||
cgValue res = cg_build_expr_internal(p, expr);
|
||||
if (res.kind == cgValue_Symbol) {
|
||||
GB_ASSERT(is_type_pointer(res.type));
|
||||
GB_ASSERT(is_type_internally_pointer_like(res.type));
|
||||
res = cg_value(tb_inst_get_symbol_address(p->func, res.symbol), res.type);
|
||||
}
|
||||
|
||||
@@ -161,6 +161,7 @@ gb_internal cgValue cg_build_expr_internal(cgProcedure *p, Ast *expr) {
|
||||
token_pos_to_string(token.pos));
|
||||
return {};
|
||||
} else if (e->kind == Entity_Nil) {
|
||||
GB_PANIC("TODO: cg_find_ident nil");
|
||||
// TODO(bill): is this correct?
|
||||
return cg_value(cast(TB_Node *)nullptr, e->type);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,127 @@
|
||||
gb_internal cgValue cg_build_call_expr(cgProcedure *p, Ast *expr) {
|
||||
ast_node(ce, CallExpr, expr);
|
||||
// TODO(bill): cg_build_call_expr
|
||||
gb_internal cgValue cg_find_procedure_value_from_entity(cgModule *m, Entity *e) {
|
||||
GB_ASSERT(is_type_proc(e->type));
|
||||
e = strip_entity_wrapping(e);
|
||||
GB_ASSERT(e != nullptr);
|
||||
GB_ASSERT(e->kind == Entity_Procedure);
|
||||
|
||||
cgValue *found = nullptr;
|
||||
rw_mutex_shared_lock(&m->values_mutex);
|
||||
found = map_get(&m->values, e);
|
||||
rw_mutex_shared_unlock(&m->values_mutex);
|
||||
if (found) {
|
||||
return *found;
|
||||
}
|
||||
|
||||
GB_PANIC("Error in: %s, missing procedure %.*s\n", token_pos_to_string(e->token.pos), LIT(e->token.string));
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
gb_internal cgValue cg_build_call_expr_internal(cgProcedure *p, Ast *expr);
|
||||
gb_internal cgValue cg_build_call_expr(cgProcedure *p, Ast *expr) {
|
||||
expr = unparen_expr(expr);
|
||||
ast_node(ce, CallExpr, expr);
|
||||
|
||||
cgValue res = cg_build_call_expr_internal(p, expr);
|
||||
|
||||
if (ce->optional_ok_one) { // TODO(bill): Minor hack for #optional_ok procedures
|
||||
GB_PANIC("Handle optional_ok_one");
|
||||
// GB_ASSERT(is_type_tuple(res.type));
|
||||
// GB_ASSERT(res.type->Tuple.variables.count == 2);
|
||||
// return cg_emit_struct_ev(p, res, 0);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
gb_internal cgValue cg_emit_call(cgProcedure * p, cgValue value, Slice<cgValue> args) {
|
||||
if (value.kind == cgValue_Symbol) {
|
||||
value = cg_value(tb_inst_get_symbol_address(p->func, value.symbol), value.type);
|
||||
}
|
||||
GB_ASSERT(value.kind == cgValue_Value);
|
||||
|
||||
TB_FunctionPrototype *proto = cg_procedure_type_as_prototype(p->module, value.type);
|
||||
TB_Node *target = value.node;
|
||||
auto params = slice_make<TB_Node *>(temporary_allocator(), 0);
|
||||
|
||||
GB_ASSERT(target != nullptr);
|
||||
TB_MultiOutput multi_output = tb_inst_call(p->func, proto, target, 0, nullptr);
|
||||
gb_unused(multi_output);
|
||||
return {};
|
||||
}
|
||||
|
||||
gb_internal cgValue cg_build_call_expr_internal(cgProcedure *p, Ast *expr) {
|
||||
ast_node(ce, CallExpr, expr);
|
||||
|
||||
TypeAndValue tv = type_and_value_of_expr(expr);
|
||||
|
||||
TypeAndValue proc_tv = type_and_value_of_expr(ce->proc);
|
||||
AddressingMode proc_mode = proc_tv.mode;
|
||||
if (proc_mode == Addressing_Type) {
|
||||
GB_ASSERT(ce->args.count == 1);
|
||||
cgValue x = cg_build_expr(p, ce->args[0]);
|
||||
return cg_emit_conv(p, x, tv.type);
|
||||
}
|
||||
|
||||
Ast *proc_expr = unparen_expr(ce->proc);
|
||||
if (proc_mode == Addressing_Builtin) {
|
||||
Entity *e = entity_of_node(proc_expr);
|
||||
BuiltinProcId id = BuiltinProc_Invalid;
|
||||
if (e != nullptr) {
|
||||
id = cast(BuiltinProcId)e->Builtin.id;
|
||||
} else {
|
||||
id = BuiltinProc_DIRECTIVE;
|
||||
}
|
||||
if (id == BuiltinProc___entry_point) {
|
||||
if (p->module->info->entry_point) {
|
||||
cgValue entry_point = cg_find_procedure_value_from_entity(p->module, p->module->info->entry_point);
|
||||
GB_ASSERT(entry_point.node != nullptr);
|
||||
cg_emit_call(p, entry_point, {});
|
||||
}
|
||||
return {};
|
||||
}
|
||||
GB_PANIC("TODO(bill): builtin procs %d %.*s", id, LIT(builtin_procs[id].name));
|
||||
}
|
||||
|
||||
// NOTE(bill): Regular call
|
||||
cgValue value = {};
|
||||
|
||||
Entity *proc_entity = entity_of_node(proc_expr);
|
||||
if (proc_entity != nullptr) {
|
||||
if (proc_entity->flags & EntityFlag_Disabled) {
|
||||
GB_ASSERT(tv.type == nullptr);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
if (proc_expr->tav.mode == Addressing_Constant) {
|
||||
ExactValue v = proc_expr->tav.value;
|
||||
switch (v.kind) {
|
||||
case ExactValue_Integer:
|
||||
{
|
||||
u64 u = big_int_to_u64(&v.value_integer);
|
||||
cgValue x = cg_value(tb_inst_uint(p->func, TB_TYPE_PTR, u), t_rawptr);
|
||||
value = cg_emit_conv(p, x, proc_expr->tav.type);
|
||||
break;
|
||||
}
|
||||
case ExactValue_Pointer:
|
||||
{
|
||||
u64 u = cast(u64)v.value_pointer;
|
||||
cgValue x = cg_value(tb_inst_uint(p->func, TB_TYPE_PTR, u), t_rawptr);
|
||||
value = cg_emit_conv(p, x, proc_expr->tav.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (value.node == nullptr) {
|
||||
value = cg_build_expr(p, proc_expr);
|
||||
}
|
||||
if (value.kind == cgValue_Addr) {
|
||||
value = cg_emit_load(p, value);
|
||||
}
|
||||
GB_ASSERT(value.kind == cgValue_Value);
|
||||
GB_ASSERT(is_type_proc(value.type));
|
||||
|
||||
return cg_emit_call(p, value, {});
|
||||
}
|
||||
|
||||
@@ -8,14 +8,16 @@ gb_internal cgValue cg_emit_load(cgProcedure *p, cgValue const &ptr, bool is_vol
|
||||
case cgValue_Value:
|
||||
return cg_lvalue_addr(ptr.node, type);
|
||||
case cgValue_Addr:
|
||||
GB_PANIC("NOT POSSIBLE");
|
||||
GB_PANIC("NOT POSSIBLE - Cannot load an lvalue to begin with");
|
||||
break;
|
||||
case cgValue_Symbol:
|
||||
return cg_lvalue_addr(tb_inst_get_symbol_address(p->func, ptr.symbol), type);
|
||||
}
|
||||
}
|
||||
|
||||
TB_CharUnits alignment = 1; // for the time being
|
||||
// use the natural alignment
|
||||
// if people need a special alignment, they can use `intrinsics.unaligned_load`
|
||||
TB_CharUnits alignment = cast(TB_CharUnits)type_align_of(type);
|
||||
|
||||
TB_Node *the_ptr = nullptr;
|
||||
switch (ptr.kind) {
|
||||
@@ -48,7 +50,9 @@ gb_internal void cg_emit_store(cgProcedure *p, cgValue dst, cgValue const &src,
|
||||
TB_DataType st = cg_data_type(src.type);
|
||||
GB_ASSERT(dt.raw == st.raw);
|
||||
|
||||
TB_CharUnits alignment = 1; // for the time being
|
||||
// use the natural alignment
|
||||
// if people need a special alignment, they can use `intrinsics.unaligned_store`
|
||||
TB_CharUnits alignment = cast(TB_CharUnits)type_align_of(dst_type);
|
||||
|
||||
if (TB_IS_VOID_TYPE(dt)) {
|
||||
TB_Node *dst_ptr = nullptr;
|
||||
@@ -281,10 +285,9 @@ gb_internal cgAddr cg_add_local(cgProcedure *p, Type *type, Entity *e, bool zero
|
||||
|
||||
if (e != nullptr && e->token.string.len > 0 && e->token.string != "_") {
|
||||
// NOTE(bill): for debugging purposes only
|
||||
char const *name = alloc_cstring(permanent_allocator(), e->token.string);
|
||||
|
||||
TB_DebugType *debug_type = cg_debug_type(p->module, type);
|
||||
tb_function_attrib_variable(p->func, local, name, debug_type);
|
||||
// String name = e->token.string;
|
||||
// TB_DebugType *debug_type = cg_debug_type(p->module, type);
|
||||
// tb_function_attrib_variable(p->func, name.len, cast(char const *)name.text, debug_type);
|
||||
}
|
||||
|
||||
if (zero_init) {
|
||||
@@ -546,7 +549,7 @@ gb_internal void cg_build_stmt(cgProcedure *p, Ast *node) {
|
||||
case_end;
|
||||
|
||||
case_ast_node(as, AssignStmt, node);
|
||||
cg_build_assign_stmt(p, as);
|
||||
// cg_build_assign_stmt(p, as);
|
||||
case_end;
|
||||
|
||||
case_ast_node(rs, ReturnStmt, node);
|
||||
|
||||
Reference in New Issue
Block a user