aboutsummaryrefslogtreecommitdiff
path: root/src/tilde_builtin.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2023-08-07 14:40:42 +0100
committergingerBill <bill@gingerbill.org>2023-08-07 14:40:42 +0100
commit0c1b39d881a5f91534bf0f33fb945ab57ef293d8 (patch)
tree5b16e10ddad44dccdb8f827294e9f3c73b68dba1 /src/tilde_builtin.cpp
parent67ffae7e32301a817d73ba68b5e0d6a626c2b4de (diff)
Mock out map get/set functionality
Diffstat (limited to 'src/tilde_builtin.cpp')
-rw-r--r--src/tilde_builtin.cpp129
1 files changed, 129 insertions, 0 deletions
diff --git a/src/tilde_builtin.cpp b/src/tilde_builtin.cpp
index f036ce583..d84506e09 100644
--- a/src/tilde_builtin.cpp
+++ b/src/tilde_builtin.cpp
@@ -231,6 +231,76 @@ gb_internal cgValue cg_builtin_mem_copy_non_overlapping(cgProcedure *p, cgValue
return dst;
}
+gb_internal TB_Symbol *cg_builtin_map_cell_info_symbol(cgModule *m, Type *type) {
+ MUTEX_GUARD(&m->map_info_mutex);
+ TB_Symbol **found = map_get(&m->map_cell_info_map, type);
+ if (found) {
+ return *found;
+ }
+ i64 size = 0, len = 0;
+ map_cell_size_and_len(type, &size, &len);
+
+ TB_Global *global = tb_global_create(m->mod, 0, "", cg_debug_type(m, t_map_cell_info), TB_LINKAGE_PRIVATE);
+ tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), global, type_size_of(t_map_cell_info), type_align_of(t_map_cell_info), 4);
+
+ i64 ptr_size = build_context.ptr_size;
+ void *size_of_type = tb_global_add_region(m->mod, global, 0*ptr_size, ptr_size);
+ void *align_of_type = tb_global_add_region(m->mod, global, 1*ptr_size, ptr_size);
+ void *size_of_cell = tb_global_add_region(m->mod, global, 2*ptr_size, ptr_size);
+ void *elements_per_cell = tb_global_add_region(m->mod, global, 3*ptr_size, ptr_size);
+
+ cg_write_uint_at_ptr(size_of_type, type_size_of(type), t_uintptr);
+ cg_write_uint_at_ptr(align_of_type, type_align_of(type), t_uintptr);
+ cg_write_uint_at_ptr(size_of_cell, size, t_uintptr);
+ cg_write_uint_at_ptr(elements_per_cell, len, t_uintptr);
+
+ map_set(&m->map_cell_info_map, type, cast(TB_Symbol *)global);
+
+ return cast(TB_Symbol *)global;
+}
+
+
+gb_internal cgValue cg_builtin_map_cell_info(cgProcedure *p, Type *type) {
+ type = core_type(type);
+ TB_Symbol *symbol = cg_builtin_map_cell_info_symbol(p->module, type);
+ TB_Node *node = tb_inst_get_symbol_address(p->func, symbol);
+ return cg_value(node, t_map_cell_info_ptr);
+}
+
+gb_internal cgValue cg_builtin_map_info(cgProcedure *p, Type *map_type) {
+ map_type = base_type(map_type);
+ GB_ASSERT(map_type->kind == Type_Map);
+
+ cgModule *m = p->module;
+ MUTEX_GUARD(&m->map_info_mutex);
+ TB_Global *global = nullptr;
+ TB_Symbol **found = map_get(&m->map_info_map, map_type);
+ if (found) {
+ global = cast(TB_Global *)*found;
+ } else {
+ global = tb_global_create(m->mod, 0, "", cg_debug_type(m, t_map_info), TB_LINKAGE_PRIVATE);
+ tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), global, type_size_of(t_map_info), type_align_of(t_map_info), 4);
+
+ TB_Symbol *key_cell_info = cg_builtin_map_cell_info_symbol(m, map_type->Map.key);
+ TB_Symbol *value_cell_info = cg_builtin_map_cell_info_symbol(m, map_type->Map.value);
+ cgProcedure *key_hasher = cg_hasher_proc_for_type(p->module, map_type->Map.key);
+ cgProcedure *key_equal = cg_equal_proc_for_type (p->module, map_type->Map.key);
+
+ tb_global_add_symbol_reloc(p->module->mod, global, 0*build_context.ptr_size, key_cell_info);
+ tb_global_add_symbol_reloc(p->module->mod, global, 1*build_context.ptr_size, value_cell_info);
+ tb_global_add_symbol_reloc(p->module->mod, global, 2*build_context.ptr_size, key_hasher->symbol);
+ tb_global_add_symbol_reloc(p->module->mod, global, 3*build_context.ptr_size, key_equal->symbol);
+
+ map_set(&m->map_info_map, map_type, cast(TB_Symbol *)global);
+ }
+
+ GB_ASSERT(global != nullptr);
+ TB_Node *node = tb_inst_get_symbol_address(p->func, cast(TB_Symbol *)global);
+ return cg_value(node, t_map_info_ptr);
+}
+
+
+
gb_internal cgValue cg_build_builtin(cgProcedure *p, BuiltinProcId id, Ast *expr) {
ast_node(ce, CallExpr, expr);
@@ -434,6 +504,65 @@ gb_internal cgValue cg_build_builtin(cgProcedure *p, BuiltinProcId id, Ast *expr
case BuiltinProc_type_hasher_proc:
return cg_hasher_proc_value_for_type(p, ce->args[0]->tav.type);
+
+ case BuiltinProc_type_map_cell_info:
+ return cg_builtin_map_cell_info(p, ce->args[0]->tav.type);
+ case BuiltinProc_type_map_info:
+ return cg_builtin_map_info(p, ce->args[0]->tav.type);
+
+ case BuiltinProc_expect:
+ {
+ Type *t = default_type(expr->tav.type);
+ cgValue x = cg_emit_conv(p, cg_build_expr(p, ce->args[0]), t);
+ cgValue y = cg_emit_conv(p, cg_build_expr(p, ce->args[1]), t);
+ gb_unused(y);
+ return x;
+ }
+
+ case BuiltinProc_count_leading_zeros:
+ {
+ cgValue n = cg_build_expr(p, ce->args[0]);
+ n = cg_emit_conv(p, n, default_type(expr->tav.type));
+ GB_ASSERT(n.kind == cgValue_Value);
+ TB_Node *val = tb_inst_clz(p->func, n.node);
+ val = tb_inst_zxt(p->func, val, cg_data_type(n.type));
+ return cg_value(val, n.type);
+ }
+
+
+ case BuiltinProc_count_trailing_zeros:
+ {
+ cgValue n = cg_build_expr(p, ce->args[0]);
+ n = cg_emit_conv(p, n, default_type(expr->tav.type));
+ GB_ASSERT(n.kind == cgValue_Value);
+ TB_Node *val = tb_inst_ctz(p->func, n.node);
+ val = tb_inst_zxt(p->func, val, cg_data_type(n.type));
+ return cg_value(val, n.type);
+ }
+
+ case BuiltinProc_count_ones:
+ {
+ cgValue n = cg_build_expr(p, ce->args[0]);
+ n = cg_emit_conv(p, n, default_type(expr->tav.type));
+ GB_ASSERT(n.kind == cgValue_Value);
+ TB_Node *val = tb_inst_popcount(p->func, n.node);
+ val = tb_inst_zxt(p->func, val, cg_data_type(n.type));
+ return cg_value(val, n.type);
+ }
+
+ case BuiltinProc_count_zeros:
+ {
+ cgValue n = cg_build_expr(p, ce->args[0]);
+ n = cg_emit_conv(p, n, default_type(expr->tav.type));
+ GB_ASSERT(n.kind == cgValue_Value);
+ TB_DataType dt = cg_data_type(n.type);
+ TB_Node *ones = tb_inst_popcount(p->func, n.node);
+ ones = tb_inst_zxt(p->func, ones, dt);
+
+ cgValue size = cg_const_int(p, n.type, 8*type_size_of(n.type));
+ return cg_emit_arith(p, Token_Sub, size, cg_value(ones, n.type), n.type);
+ }
+
}