From 64bd884d94fc45600eaed9566585d455b875a87a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 23 Feb 2019 14:42:44 +0000 Subject: Add "none" calling convention --- src/types.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/types.cpp') diff --git a/src/types.cpp b/src/types.cpp index 52c06ef71..859805f29 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -2894,6 +2894,9 @@ gbString write_type_to_string(gbString str, Type *type) { case ProcCC_FastCall: str = gb_string_appendc(str, " \"fastcall\" "); break; + case ProcCC_None: + str = gb_string_appendc(str, " \"none\" "); + break; // case ProcCC_VectorCall: // str = gb_string_appendc(str, " \"vectorcall\" "); // break; -- cgit v1.2.3 From 4c51384ad64a2f63863e6bacab7aeee881659047 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 23 Feb 2019 16:44:16 +0000 Subject: `intrinsics.vector` type (Experimental) --- core/fmt/fmt.odin | 24 +++++++++ core/runtime/core.odin | 8 ++- core/types/types.odin | 5 ++ src/check_expr.cpp | 54 +++++++++++++++++++ src/checker.cpp | 19 +++++++ src/checker.hpp | 5 ++ src/ir.cpp | 13 +++++ src/ir_print.cpp | 35 ++++++++++++ src/types.cpp | 144 ++++++++++++++++++++++++++++--------------------- 9 files changed, 246 insertions(+), 61 deletions(-) (limited to 'src/types.cpp') diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index c4a535d77..0df06c0ec 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -1008,6 +1008,20 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { fmt_arg(fi, any{rawptr(data), info.elem.id}, verb); } + case runtime.Type_Info_Simd_Vector: + if info.is_x86_mmx { + strings.write_string(fi.buf, "intrinsics.x86_mmx<>"); + } + strings.write_byte(fi.buf, '<'); + defer strings.write_byte(fi.buf, '>'); + for i in 0..info.count-1 { + if i > 0 do strings.write_string(fi.buf, ", "); + + data := uintptr(v.data) + uintptr(i*info.elem_size); + fmt_arg(fi, any{rawptr(data), info.elem.id}, verb); + } + + case runtime.Type_Info_Slice: strings.write_byte(fi.buf, '['); defer strings.write_byte(fi.buf, ']'); @@ -1448,5 +1462,15 @@ write_type :: proc(buf: ^strings.Builder, ti: ^runtime.Type_Info) { write_string(buf, "opaque "); write_type(buf, info.elem); + case runtime.Type_Info_Simd_Vector: + if info.is_x86_mmx { + write_string(buf, "intrinsics.x86_mmx"); + } else { + write_string(buf, "intrinsics.vector("); + write_i64(buf, i64(info.count)); + write_string(buf, ", "); + write_type(buf, info.elem); + write_byte(buf, ')'); + } } } diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 9307b5589..38dd8f225 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -112,9 +112,14 @@ Type_Info_Bit_Set :: struct { lower: i64, upper: i64, }; - Type_Info_Opaque :: struct { elem: ^Type_Info, +}; +Type_Info_Simd_Vector :: struct { + elem: ^Type_Info, + elem_size: int, + count: int, + is_x86_mmx: bool, } Type_Info :: struct { @@ -145,6 +150,7 @@ Type_Info :: struct { Type_Info_Bit_Field, Type_Info_Bit_Set, Type_Info_Opaque, + Type_Info_Simd_Vector, }, } diff --git a/core/types/types.odin b/core/types/types.odin index 485530fea..dc4db549f 100644 --- a/core/types/types.odin +++ b/core/types/types.odin @@ -267,3 +267,8 @@ is_opaque :: proc(info: ^rt.Type_Info) -> bool { _, ok := rt.type_info_base(info).variant.(rt.Type_Info_Opaque); return ok; } +is_simd_vector :: proc(info: ^rt.Type_Info) -> bool { + if info == nil do return false; + _, ok := rt.type_info_base(info).variant.(rt.Type_Info_Simd_Vector); + return ok; +} diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 79f980a79..75c16b705 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -4072,6 +4072,46 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 break; } + case BuiltinProc_vector: { + Operand x = {}; + Operand y = {}; + x = *operand; + if (!is_type_integer(x.type) || x.mode != Addressing_Constant) { + error(call, "Expected a constant integer for 'intrinsics.vector'"); + operand->mode = Addressing_Type; + operand->type = t_invalid; + return false; + } + if (x.value.value_integer.neg) { + error(call, "Negative vector element length"); + operand->mode = Addressing_Type; + operand->type = t_invalid; + return false; + } + i64 count = big_int_to_i64(&x.value.value_integer); + + check_expr_or_type(c, &y, ce->args[1]); + if (y.mode != Addressing_Type) { + error(call, "Expected a type 'intrinsics.vector'"); + operand->mode = Addressing_Type; + operand->type = t_invalid; + return false; + } + Type *elem = y.type; + if (!is_type_valid_vector_elem(elem)) { + gbString str = type_to_string(elem); + error(call, "Invalid element type for 'intrinsics.vector', expected an integer or float with no specific endianness, got '%s'", str); + gb_string_free(str); + operand->mode = Addressing_Type; + operand->type = t_invalid; + return false; + } + + operand->mode = Addressing_Type; + operand->type = alloc_type_simd_vector(count, elem); + break; + } + case BuiltinProc_atomic_fence: case BuiltinProc_atomic_fence_acq: case BuiltinProc_atomic_fence_rel: @@ -5902,6 +5942,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type case Type_Slice: case Type_Array: case Type_DynamicArray: + case Type_SimdVector: { Type *elem_type = nullptr; String context_name = {}; @@ -5922,6 +5963,10 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type add_package_dependency(c, "runtime", "__dynamic_array_reserve"); add_package_dependency(c, "runtime", "__dynamic_array_append"); + } else if (t->kind == Type_SimdVector) { + elem_type = t->SimdVector.elem; + context_name = str_lit("simd vector literal"); + max_type_count = t->SimdVector.count; } else { GB_PANIC("unreachable"); } @@ -5972,6 +6017,15 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type error(node, "Expected %lld values for this array literal, got %lld", cast(long long)t->Array.count, cast(long long)max); } } + + if (t->kind == Type_SimdVector) { + if (!is_constant) { + error(node, "Expected all constant elements for a simd vector"); + } + if (t->SimdVector.is_x86_mmx) { + error(node, "Compound literals are not allowed with intrinsics.x86_mmx"); + } + } break; } diff --git a/src/checker.cpp b/src/checker.cpp index 9cac82911..7900555a5 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -712,6 +712,15 @@ void init_universal(void) { } } + // TODO(bill): Set the correct arch for this + if (bc->metrics.arch == TargetArch_amd64 || bc->metrics.arch == TargetArch_386) { + t_vector_x86_mmx = alloc_type(Type_SimdVector); + t_vector_x86_mmx->SimdVector.is_x86_mmx = true; + + Entity *entity = alloc_entity(Entity_TypeName, nullptr, make_token_ident(str_lit("x86_mmx")), t_vector_x86_mmx); + add_global_entity(entity, intrinsics_pkg->scope); + } + t_u8_ptr = alloc_type_pointer(t_u8); t_int_ptr = alloc_type_pointer(t_int); @@ -1248,6 +1257,10 @@ void add_type_info_type(CheckerContext *c, Type *t) { add_type_info_type(c, bt->Proc.results); break; + case Type_SimdVector: + add_type_info_type(c, bt->SimdVector.elem); + break; + default: GB_PANIC("Unhandled type: %*.s %d", LIT(type_strings[bt->kind]), bt->kind); break; @@ -1419,6 +1432,10 @@ void add_min_dep_type_info(Checker *c, Type *t) { add_min_dep_type_info(c, bt->Proc.results); break; + case Type_SimdVector: + add_min_dep_type_info(c, bt->SimdVector.elem); + break; + default: GB_PANIC("Unhandled type: %*.s", LIT(type_strings[bt->kind])); break; @@ -1795,6 +1812,7 @@ void init_core_type_info(Checker *c) { t_type_info_bit_field = find_core_type(c, str_lit("Type_Info_Bit_Field")); t_type_info_bit_set = find_core_type(c, str_lit("Type_Info_Bit_Set")); t_type_info_opaque = find_core_type(c, str_lit("Type_Info_Opaque")); + t_type_info_simd_vector = find_core_type(c, str_lit("Type_Info_Simd_Vector")); t_type_info_named_ptr = alloc_type_pointer(t_type_info_named); t_type_info_integer_ptr = alloc_type_pointer(t_type_info_integer); @@ -1818,6 +1836,7 @@ void init_core_type_info(Checker *c) { t_type_info_bit_field_ptr = alloc_type_pointer(t_type_info_bit_field); t_type_info_bit_set_ptr = alloc_type_pointer(t_type_info_bit_set); t_type_info_opaque_ptr = alloc_type_pointer(t_type_info_opaque); + t_type_info_simd_vector_ptr = alloc_type_pointer(t_type_info_simd_vector); } void init_mem_allocator(Checker *c) { diff --git a/src/checker.hpp b/src/checker.hpp index abc349129..de491671e 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -89,6 +89,8 @@ enum BuiltinProcId { BuiltinProc_DIRECTIVE, // NOTE(bill): This is used for specialized hash-prefixed procedures // "Intrinsics" + BuiltinProc_vector, + BuiltinProc_atomic_fence, BuiltinProc_atomic_fence_acq, BuiltinProc_atomic_fence_rel, @@ -194,6 +196,9 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { // "Intrinsics" + {STR_LIT("vector"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, // Type + + {STR_LIT("atomic_fence"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, {STR_LIT("atomic_fence_acq"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, {STR_LIT("atomic_fence_rel"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, diff --git a/src/ir.cpp b/src/ir.cpp index cd7e8d99a..4df6665f7 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -7268,6 +7268,7 @@ irAddr ir_build_addr(irProcedure *proc, Ast *expr) { case Type_Array: et = bt->Array.elem; break; case Type_Slice: et = bt->Slice.elem; break; case Type_BitSet: et = bt->BitSet.elem; break; + case Type_SimdVector: et = bt->SimdVector.elem; break; } String proc_name = {}; @@ -9995,6 +9996,18 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info tag = ir_emit_conv(proc, variant_ptr, t_type_info_opaque_ptr); ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), ir_get_type_info_ptr(proc, t->Opaque.elem)); break; + + case Type_SimdVector: + ir_emit_comment(proc, str_lit("Type_SimdVector")); + tag = ir_emit_conv(proc, variant_ptr, t_type_info_simd_vector_ptr); + if (t->SimdVector.is_x86_mmx) { + ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 3), v_true); + } else { + ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), ir_get_type_info_ptr(proc, t->SimdVector.elem)); + ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 1), ir_const_int(type_size_of(t->SimdVector.elem))); + ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 2), ir_const_int(t->SimdVector.count)); + } + break; } diff --git a/src/ir_print.cpp b/src/ir_print.cpp index c6e717f74..0cc9f52e3 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -574,6 +574,16 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t, bool in_struct) { case Type_Opaque: ir_print_type(f, m, strip_opaque_type(t)); return; + + case Type_SimdVector: + if (t->SimdVector.is_x86_mmx) { + ir_write_str_lit(f, "x86_mmx"); + } else { + ir_fprintf(f, "<%lld x ", t->SimdVector.count);; + ir_print_type(f, m, t->SimdVector.elem); + ir_write_byte(f, '>'); + } + return; } } @@ -802,6 +812,31 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type * } ir_write_byte(f, ']'); + } else if (is_type_simd_vector(type)) { + ast_node(cl, CompoundLit, value.value_compound); + + Type *elem_type = type->SimdVector.elem; + isize elem_count = cl->elems.count; + if (elem_count == 0) { + ir_write_str_lit(f, "zeroinitializer"); + break; + } + GB_ASSERT_MSG(elem_count == type->SimdVector.count, "%td != %td", elem_count, type->SimdVector.count); + + ir_write_byte(f, '<'); + + for (isize i = 0; i < elem_count; i++) { + if (i > 0) ir_write_str_lit(f, ", "); + TypeAndValue tav = cl->elems[i]->tav; + GB_ASSERT(tav.mode != Addressing_Invalid); + ir_print_compound_element(f, m, tav.value, elem_type); + } + for (isize i = elem_count; i < type->SimdVector.count; i++) { + if (i >= elem_count) ir_write_str_lit(f, ", "); + ir_print_compound_element(f, m, empty_exact_value, elem_type); + } + + ir_write_byte(f, '>'); } else if (is_type_struct(type)) { gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&m->tmp_arena); defer (gb_temp_arena_memory_end(tmp)); diff --git a/src/types.cpp b/src/types.cpp index 859805f29..6dcbf029f 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -215,6 +215,12 @@ struct TypeUnion { i64 lower; \ i64 upper; \ }) \ + TYPE_KIND(SimdVector, struct { \ + i64 count; \ + Type *elem; \ + bool is_x86_mmx; \ + }) \ + @@ -460,13 +466,13 @@ gb_global Type *t_type_info_map = nullptr; gb_global Type *t_type_info_bit_field = nullptr; gb_global Type *t_type_info_bit_set = nullptr; gb_global Type *t_type_info_opaque = nullptr; +gb_global Type *t_type_info_simd_vector = nullptr; gb_global Type *t_type_info_named_ptr = nullptr; gb_global Type *t_type_info_integer_ptr = nullptr; gb_global Type *t_type_info_rune_ptr = nullptr; gb_global Type *t_type_info_float_ptr = nullptr; gb_global Type *t_type_info_complex_ptr = nullptr; -gb_global Type *t_type_info_quaternion_ptr = nullptr; gb_global Type *t_type_info_any_ptr = nullptr; gb_global Type *t_type_info_typeid_ptr = nullptr; gb_global Type *t_type_info_string_ptr = nullptr; @@ -484,6 +490,7 @@ gb_global Type *t_type_info_map_ptr = nullptr; gb_global Type *t_type_info_bit_field_ptr = nullptr; gb_global Type *t_type_info_bit_set_ptr = nullptr; gb_global Type *t_type_info_opaque_ptr = nullptr; +gb_global Type *t_type_info_simd_vector_ptr = nullptr; gb_global Type *t_allocator = nullptr; gb_global Type *t_allocator_ptr = nullptr; @@ -496,6 +503,8 @@ gb_global Type *t_source_code_location_ptr = nullptr; gb_global Type *t_map_key = nullptr; gb_global Type *t_map_header = nullptr; +gb_global Type *t_vector_x86_mmx = nullptr; + i64 type_size_of (Type *t); @@ -722,6 +731,13 @@ Type *alloc_type_bit_set() { +Type *alloc_type_simd_vector(i64 count, Type *elem) { + Type *t = alloc_type(Type_SimdVector); + t->SimdVector.count = count; + t->SimdVector.elem = elem; + return t; +} + //////////////////////////////////////////////////////////////// @@ -971,6 +987,11 @@ bool is_type_generic(Type *t) { return t->kind == Type_Generic; } +bool is_type_simd_vector(Type *t) { + t = base_type(t); + return t->kind == Type_SimdVector; +} + Type *core_array_type(Type *t) { for (;;) { @@ -1193,6 +1214,25 @@ Type *bit_set_to_int(Type *t) { return nullptr; } +bool is_type_valid_vector_elem(Type *t) { + t = base_type(t); + if (t->kind == Type_Basic) { + if (t->Basic.flags & BasicFlag_EndianLittle) { + return false; + } + if (t->Basic.flags & BasicFlag_EndianBig) { + return false; + } + if (is_type_integer(t)) { + return true; + } + if (is_type_float(t)) { + return true; + } + } + return false; +} + bool is_type_indexable(Type *t) { Type *bt = base_type(t); @@ -1637,6 +1677,18 @@ bool are_types_identical(Type *x, Type *y) { are_types_identical(x->Map.value, y->Map.value); } break; + + case Type_SimdVector: + if (y->kind == Type_SimdVector) { + if (x->SimdVector.is_x86_mmx == y->SimdVector.is_x86_mmx) { + if (x->SimdVector.is_x86_mmx) { + return true; + } else if (x->SimdVector.count == y->SimdVector.count) { + return are_types_identical(x->SimdVector.elem, y->SimdVector.elem); + } + } + } + break; } return false; @@ -1681,65 +1733,6 @@ Type *default_type(Type *type) { return type; } -/* -// NOTE(bill): Valid Compile time execution #run type -bool is_type_cte_safe(Type *type) { - type = default_type(base_type(type)); - switch (type->kind) { - case Type_Basic: - switch (type->Basic.kind) { - case Basic_rawptr: - case Basic_any: - return false; - } - return true; - - case Type_Pointer: - return false; - - case Type_Array: - return is_type_cte_safe(type->Array.elem); - - case Type_DynamicArray: - return false; - case Type_Map: - return false; - - case Type_Slice: - return false; - - case Type_Struct: { - if (type->Struct.is_raw_union) { - return false; - } - for_array(i, type->Struct.fields) { - Entity *v = type->Struct.fields[i]; - if (!is_type_cte_safe(v->type)) { - return false; - } - } - return true; - } - - case Type_Tuple: { - for_array(i, type->Tuple.variables) { - Entity *v = type->Tuple.variables[i]; - if (!is_type_cte_safe(v->type)) { - return false; - } - } - return true; - } - - case Type_Proc: - // TODO(bill): How should I handle procedures in the CTE stage? - // return type->Proc.calling_convention == ProcCC_Odin; - return false; - } - - return false; -} - */ i64 union_variant_index(Type *u, Type *v) { u = base_type(u); GB_ASSERT(u->kind == Type_Union); @@ -2389,7 +2382,18 @@ i64 type_align_of_internal(Type *t, TypePath *path) { if (bits <= 32) return 4; if (bits <= 64) return 8; return 8; // NOTE(bill): Could be an invalid range so limit it for now + } + case Type_SimdVector: { + if (t->SimdVector.is_x86_mmx) { + return 8; + } + // align of + i64 count = t->SimdVector.count; + Type *elem = t->SimdVector.elem; + i64 size = count * type_size_of_internal(elem, path); + // IMPORTANT TODO(bill): Figure out the alignment of vector types + return gb_clamp(next_pow2(type_size_of_internal(t, path)), 1, build_context.max_align); } } @@ -2622,6 +2626,15 @@ i64 type_size_of_internal(Type *t, TypePath *path) { if (bits <= 64) return 8; return 8; // NOTE(bill): Could be an invalid range so limit it for now } + + case Type_SimdVector: { + if (t->SimdVector.is_x86_mmx) { + return 8; + } + i64 count = t->SimdVector.count; + Type *elem = t->SimdVector.elem; + return count * type_size_of_internal(elem, path); + } } // Catch all @@ -2950,6 +2963,17 @@ gbString write_type_to_string(gbString str, Type *type) { } str = gb_string_appendc(str, "]"); break; + + case Type_SimdVector: + if (type->SimdVector.is_x86_mmx) { + return "intrinsics.x86_mmx"; + } else { + str = gb_string_appendc(str, "intrinsics.vector("); + str = gb_string_append_fmt(str, "%d, ", cast(int)type->SimdVector.count); + str = write_type_to_string(str, type->SimdVector.elem); + str = gb_string_appendc(str, ")"); + } + break; } return str; -- cgit v1.2.3 From 38ae2e9efaf8d227a138d749085599e7ee9fde54 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 23 Feb 2019 18:05:41 +0000 Subject: Allow basic arithmetic operations for vectors --- src/ir_print.cpp | 2 +- src/types.cpp | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'src/types.cpp') diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 0cc9f52e3..af5abe180 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -1700,7 +1700,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { case irInstr_BinaryOp: { irInstrBinaryOp *bo = &value->Instr.BinaryOp; Type *type = base_type(ir_type(bo->left)); - Type *elem_type = type; + Type *elem_type = base_array_type(type); ir_fprintf(f, "%%%d = ", value->index); diff --git a/src/types.cpp b/src/types.cpp index 6dcbf029f..c6886e984 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -974,11 +974,20 @@ bool is_type_poly_proc(Type *t) { t = base_type(t); return t->kind == Type_Proc && t->Proc.is_polymorphic; } +bool is_type_simd_vector(Type *t) { + t = base_type(t); + return t->kind == Type_SimdVector; +} + Type *base_array_type(Type *t) { if (is_type_array(t)) { t = base_type(t); return t->Array.elem; } + if (is_type_simd_vector(t)) { + t = base_type(t); + return t->SimdVector.elem; + } return t; } @@ -987,10 +996,6 @@ bool is_type_generic(Type *t) { return t->kind == Type_Generic; } -bool is_type_simd_vector(Type *t) { - t = base_type(t); - return t->kind == Type_SimdVector; -} Type *core_array_type(Type *t) { -- cgit v1.2.3 From bdab5e00da6dee80b7582135815f2183def935bb Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 11 Mar 2019 19:52:40 +0000 Subject: Minor code clean up --- core/odin/parser/parser.odin | 27 +++++++++++++++++++++++++-- core/runtime/core.odin | 30 ++++++++++++------------------ src/check_expr.cpp | 3 ++- src/check_type.cpp | 1 + src/parser.hpp | 1 - src/types.cpp | 1 + 6 files changed, 41 insertions(+), 22 deletions(-) (limited to 'src/types.cpp') diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index 17a24c5f5..ccae59a7c 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -1077,9 +1077,9 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt { stmt := parse_stmt(p); switch name { case "bounds_check": - stmt.state_flags |= {ast.Node_State_Flag.Bounds_Check}; + stmt.state_flags |= {.Bounds_Check}; case "no_bounds_check": - stmt.state_flags |= {ast.Node_State_Flag.No_Bounds_Check}; + stmt.state_flags |= {.No_Bounds_Check}; } return stmt; case "complete": @@ -1723,6 +1723,29 @@ string_to_calling_convention :: proc(s: string) -> ast.Proc_Calling_Convention { return Invalid; } +parse_proc_tags :: proc(p: ^Parser) -> (tags: Proc_Tags) { + for p.curr_tok.kind == token.Hash { + tok := expect_token(p, token.Hash); + ident := expect_token(p, token.Ident); + + switch ident.text { + case "require_results": + tags |= {.Require_Results}; + case "bounds_check": + tags |= {.Bounds_Check}; + case "no_bounds_check": + tags |= {.No_Bounds_Check}; + case: + } + } + + if .Bounds_Check in tags && .No_Bounds_Check in tags { + p.err(p.curr_tok.pos, "#bounds_check and #no_bounds_check applied to the same procedure type"); + } + + return; +} + parse_proc_type :: proc(p: ^Parser, tok: token.Token) -> ^ast.Proc_Type { cc := ast.Proc_Calling_Convention.Invalid; if p.curr_tok.kind == token.String { diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 38dd8f225..1ce7cfac5 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -251,8 +251,10 @@ Map_Entry_Header :: struct { Map_Header :: struct { m: ^mem.Raw_Map, is_key_string: bool, + entry_size: int, entry_align: int, + value_offset: uintptr, value_size: int, } @@ -833,29 +835,23 @@ __get_map_key :: proc "contextless" (key: $K) -> Map_Key { return map_key; } +_fnv64a :: proc(data: []byte, seed: u64 = 0xcbf29ce484222325) -> u64 { + h: u64 = seed; + for b in data { + h = (h ~ u64(b)) * 0x100000001b3; + } + return h; +} + default_hash :: proc(data: []byte) -> u64 { - fnv64a :: proc(data: []byte) -> u64 { - h: u64 = 0xcbf29ce484222325; - for b in data { - h = (h ~ u64(b)) * 0x100000001b3; - } - return h; - } - return fnv64a(data); + return _fnv64a(data); } default_hash_string :: proc(s: string) -> u64 do return default_hash(([]byte)(s)); source_code_location_hash :: proc(s: Source_Code_Location) -> u64 { - fnv64a :: proc(data: []byte, seed: u64 = 0xcbf29ce484222325) -> u64 { - h: u64 = seed; - for b in data { - h = (h ~ u64(b)) * 0x100000001b3; - } - return h; - } - hash := fnv64a(cast([]byte)s.file_path); + hash := _fnv64a(cast([]byte)s.file_path); hash = hash ~ (u64(s.line) * 0x100000001b3); hash = hash ~ (u64(s.column) * 0x100000001b3); return hash; @@ -863,7 +859,6 @@ source_code_location_hash :: proc(s: Source_Code_Location) -> u64 { - __slice_resize :: proc(array_: ^$T/[]$E, new_count: int, allocator: mem.Allocator, loc := #caller_location) -> bool { array := (^mem.Raw_Slice)(array_); @@ -942,7 +937,6 @@ __dynamic_map_get :: proc(h: Map_Header, key: Map_Key) -> rawptr { } __dynamic_map_set :: proc(h: Map_Header, key: Map_Key, value: rawptr, loc := #caller_location) #no_bounds_check { - index: int; assert(value != nil); diff --git a/src/check_expr.cpp b/src/check_expr.cpp index f533a1812..d0e18d89f 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -5439,7 +5439,8 @@ ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call) { operand->mode = Addressing_NoValue; } else { GB_ASSERT(is_type_tuple(result_type)); - switch (result_type->Tuple.variables.count) { + isize count = result_type->Tuple.variables.count; + switch (count) { case 0: operand->mode = Addressing_NoValue; break; diff --git a/src/check_type.cpp b/src/check_type.cpp index 1c5d5ac85..451a388fb 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -2049,6 +2049,7 @@ bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node, type->Proc.is_polymorphic = pt->generic; type->Proc.specialization_count = specialization_count; type->Proc.diverging = pt->diverging; + type->Proc.tags = pt->tags; if (param_count > 0) { Entity *end = params->Tuple.variables[param_count-1]; diff --git a/src/parser.hpp b/src/parser.hpp index 816f3f534..e08648eca 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -151,7 +151,6 @@ enum ProcTag { ProcTag_bounds_check = 1<<0, ProcTag_no_bounds_check = 1<<1, ProcTag_require_results = 1<<4, - ProcTag_no_context = 1<<6, }; enum ProcCallingConvention { diff --git a/src/types.cpp b/src/types.cpp index c6886e984..5aa2ab6e1 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -198,6 +198,7 @@ struct TypeUnion { bool has_proc_default_values; \ bool has_named_results; \ bool diverging; /* no return */ \ + u64 tags; \ isize specialization_count; \ ProcCallingConvention calling_convention; \ }) \ -- cgit v1.2.3