diff options
| author | gingerBill <bill@gingerbill.org> | 2023-07-23 22:07:21 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2023-07-23 22:07:21 +0100 |
| commit | 2f9c5d2d0b500518acecb9badd4b6947db6fd536 (patch) | |
| tree | b0a927ef7821a3b0559a7aed981df9ffe095fc68 /src | |
| parent | 99c812b02d31d8f827e299ff7bb4a5d0c59bed4b (diff) | |
Minor clean up to builtin procs
Diffstat (limited to 'src')
| -rw-r--r-- | src/tilde_builtin.cpp | 136 |
1 files changed, 120 insertions, 16 deletions
diff --git a/src/tilde_builtin.cpp b/src/tilde_builtin.cpp index c55cfbb75..6deaf0e9b 100644 --- a/src/tilde_builtin.cpp +++ b/src/tilde_builtin.cpp @@ -12,6 +12,7 @@ gb_internal cgValue cg_builtin_len(cgProcedure *p, cgValue value) { return cg_emit_load(p, len_ptr); } case Basic_cstring: + GB_PANIC("TODO(bill): len(cstring)"); break; } break; @@ -51,6 +52,69 @@ gb_internal cgValue cg_builtin_len(cgProcedure *p, cgValue value) { return {}; } +gb_internal cgValue cg_builtin_cap(cgProcedure *p, cgValue value) { + Type *t = base_type(value.type); + + switch (t->kind) { + case Type_Basic: + switch (t->Basic.kind) { + case Basic_string: + { + GB_ASSERT(value.kind == cgValue_Addr); + cgValue ptr = cg_value(value.node, alloc_type_pointer(value.type)); + cgValue len_ptr = cg_emit_struct_ep(p, ptr, 1); + return cg_emit_load(p, len_ptr); + } + case Basic_cstring: + GB_PANIC("TODO(bill): cap(cstring)"); + break; + } + break; + case Type_Array: + return cg_const_int(p, t_int, t->Array.count); + case Type_EnumeratedArray: + return cg_const_int(p, t_int, t->EnumeratedArray.count); + case Type_Slice: + { + GB_ASSERT(value.kind == cgValue_Addr); + cgValue ptr = cg_value(value.node, alloc_type_pointer(value.type)); + cgValue len_ptr = cg_emit_struct_ep(p, ptr, 1); + return cg_emit_load(p, len_ptr); + } + case Type_DynamicArray: + { + GB_ASSERT(value.kind == cgValue_Addr); + cgValue ptr = cg_value(value.node, alloc_type_pointer(value.type)); + cgValue len_ptr = cg_emit_struct_ep(p, ptr, 2); + return cg_emit_load(p, len_ptr); + } + case Type_Map: + { + TB_DataType dt_uintptr = cg_data_type(t_uintptr); + TB_Node *zero = tb_inst_uint(p->func, dt_uintptr, 0); + TB_Node *one = tb_inst_uint(p->func, dt_uintptr, 0); + TB_Node *mask = tb_inst_uint(p->func, dt_uintptr, MAP_CACHE_LINE_SIZE-1); + + TB_Node *data = cg_emit_struct_ev(p, value, 0).node; + TB_Node *log2_cap = tb_inst_and(p->func, data, mask); + TB_Node *cap = tb_inst_shl(p->func, one, log2_cap, cast(TB_ArithmeticBehavior)0); + TB_Node *cmp = tb_inst_cmp_eq(p->func, data, zero); + + cgValue res = cg_value(tb_inst_select(p->func, cmp, zero, cap), t_uintptr); + return cg_emit_conv(p, res, t_int); + } + case Type_Struct: + GB_ASSERT(is_type_soa_struct(t)); + break; + case Type_RelativeSlice: + break; + } + + GB_PANIC("TODO(bill): cg_builtin_cap %s", type_to_string(t)); + return {}; +} + + gb_internal cgValue cg_builtin_raw_data(cgProcedure *p, cgValue const &value) { Type *t = base_type(value.type); cgValue res = {}; @@ -108,7 +172,7 @@ gb_internal cgValue cg_builtin_max(cgProcedure *p, Type *t, cgValue x, cgValue y return cg_emit_select(p, cg_emit_comp(p, Token_Gt, x, y), x, y); } -gb_internal cgValue cg_builtin_abs(cgProcedure *p, cgValue x) { +gb_internal cgValue cg_builtin_abs(cgProcedure *p, cgValue const &x) { if (is_type_unsigned(x.type)) { return x; } @@ -138,6 +202,39 @@ gb_internal cgValue cg_builtin_abs(cgProcedure *p, cgValue x) { return cg_emit_select(p, cond, neg, x); } +gb_internal cgValue cg_builtin_clamp(cgProcedure *p, Type *t, cgValue const &x, cgValue const &min, cgValue const &max) { + cgValue z = x; + z = cg_builtin_max(p, t, z, min); + z = cg_builtin_min(p, t, z, max); + return z; +} + + + +gb_internal cgValue cg_builtin_mem_zero(cgProcedure *p, cgValue const &ptr, cgValue const &len) { + GB_ASSERT(ptr.kind == cgValue_Value); + GB_ASSERT(len.kind == cgValue_Value); + tb_inst_memzero(p->func, ptr.node, len.node, 1, false); + return ptr; +} + +gb_internal cgValue cg_builtin_mem_copy(cgProcedure *p, cgValue const &dst, cgValue const &src, cgValue const &len) { + GB_ASSERT(dst.kind == cgValue_Value); + GB_ASSERT(src.kind == cgValue_Value); + GB_ASSERT(len.kind == cgValue_Value); + // TODO(bill): This needs to be memmove + tb_inst_memcpy(p->func, dst.node, src.node, len.node, 1, false); + return dst; +} + +gb_internal cgValue cg_builtin_mem_copy_non_overlapping(cgProcedure *p, cgValue const &dst, cgValue const &src, cgValue const &len) { + GB_ASSERT(dst.kind == cgValue_Value); + GB_ASSERT(src.kind == cgValue_Value); + GB_ASSERT(len.kind == cgValue_Value); + tb_inst_memcpy(p->func, dst.node, src.node, len.node, 1, false); + return dst; +} + gb_internal cgValue cg_build_builtin(cgProcedure *p, BuiltinProcId id, Ast *expr) { @@ -186,6 +283,17 @@ gb_internal cgValue cg_build_builtin(cgProcedure *p, BuiltinProcId id, Ast *expr return cg_builtin_len(p, v); } + case BuiltinProc_cap: { + cgValue v = cg_build_expr(p, ce->args[0]); + Type *t = base_type(v.type); + if (is_type_pointer(t)) { + // IMPORTANT TODO(bill): Should there be a nil pointer check? + v = cg_emit_load(p, v); + t = type_deref(t); + } + return cg_builtin_cap(p, v); + } + case BuiltinProc_raw_data: { cgValue v = cg_build_expr(p, ce->args[0]); @@ -225,6 +333,14 @@ gb_internal cgValue cg_build_builtin(cgProcedure *p, BuiltinProcId id, Ast *expr return cg_builtin_abs(p, x); } + case BuiltinProc_clamp: + { + cgValue x = cg_build_expr(p, ce->args[0]); + cgValue min = cg_build_expr(p, ce->args[1]); + cgValue max = cg_build_expr(p, ce->args[2]); + return cg_builtin_clamp(p, type_of_expr(expr), x, min, max); + } + case BuiltinProc_debug_trap: tb_inst_debugbreak(p->func); return {}; @@ -236,10 +352,7 @@ gb_internal cgValue cg_build_builtin(cgProcedure *p, BuiltinProcId id, Ast *expr { cgValue ptr = cg_build_expr(p, ce->args[0]); cgValue len = cg_build_expr(p, ce->args[1]); - GB_ASSERT(ptr.kind == cgValue_Value); - GB_ASSERT(len.kind == cgValue_Value); - tb_inst_memzero(p->func, ptr.node, len.node, 1, false); - return {}; + return cg_builtin_mem_zero(p, ptr, len); } case BuiltinProc_mem_copy: @@ -247,12 +360,7 @@ gb_internal cgValue cg_build_builtin(cgProcedure *p, BuiltinProcId id, Ast *expr cgValue dst = cg_build_expr(p, ce->args[0]); cgValue src = cg_build_expr(p, ce->args[1]); cgValue len = cg_build_expr(p, ce->args[2]); - GB_ASSERT(dst.kind == cgValue_Value); - GB_ASSERT(src.kind == cgValue_Value); - GB_ASSERT(len.kind == cgValue_Value); - // TODO(bill): This needs to be memmove - tb_inst_memcpy(p->func, dst.node, src.node, len.node, 1, false); - return {}; + return cg_builtin_mem_copy(p, dst, src, len); } case BuiltinProc_mem_copy_non_overlapping: @@ -260,11 +368,7 @@ gb_internal cgValue cg_build_builtin(cgProcedure *p, BuiltinProcId id, Ast *expr cgValue dst = cg_build_expr(p, ce->args[0]); cgValue src = cg_build_expr(p, ce->args[1]); cgValue len = cg_build_expr(p, ce->args[2]); - GB_ASSERT(dst.kind == cgValue_Value); - GB_ASSERT(src.kind == cgValue_Value); - GB_ASSERT(len.kind == cgValue_Value); - tb_inst_memcpy(p->func, dst.node, src.node, len.node, 1, false); - return {}; + return cg_builtin_mem_copy_non_overlapping(p, dst, src, len); } |