From b032d5af87ebe8d9dee28698cfa570d3628e58e5 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 25 May 2022 17:26:18 +0100 Subject: [PATCH] Make `#simd` an opaque type --- src/check_decl.cpp | 20 +++++++++++++------- src/check_expr.cpp | 24 ++++++++---------------- src/check_type.cpp | 5 +++++ src/common.cpp | 7 +++++++ src/types.cpp | 2 +- 5 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 82ac6c677..d8cad2ce1 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -313,13 +313,19 @@ void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def) } named->Named.base = base; - if (is_distinct && is_type_typeid(e->type)) { - error(init_expr, "'distinct' cannot be applied to 'typeid'"); - is_distinct = false; - } - if (is_distinct && is_type_any(e->type)) { - error(init_expr, "'distinct' cannot be applied to 'any'"); - is_distinct = false; + if (is_distinct) { + if (is_type_typeid(e->type)) { + error(init_expr, "'distinct' cannot be applied to 'typeid'"); + is_distinct = false; + } else if (is_type_any(e->type)) { + error(init_expr, "'distinct' cannot be applied to 'any'"); + is_distinct = false; + } else if (is_type_simd_vector(e->type)) { + gbString str = type_to_string(e->type); + error(init_expr, "'distinct' cannot be applied to '%s'", str); + gb_string_free(str); + is_distinct = false; + } } if (!is_distinct) { e->type = bt; diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 7b269e048..a4dfade98 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -1567,9 +1567,16 @@ bool check_unary_op(CheckerContext *c, Operand *o, Token op) { bool check_binary_op(CheckerContext *c, Operand *o, Token op) { Type *main_type = o->type; + + if (is_type_simd_vector(main_type)) { + error(op, "Operator '%.*s' is not supported on #simd vector types, please use the intrinsics.simd_*", LIT(op.string)); + return false; + } + // TODO(bill): Handle errors correctly Type *type = base_type(core_array_type(main_type)); Type *ct = core_type(type); + switch (op.kind) { case Token_Sub: case Token_SubEq: @@ -1638,14 +1645,6 @@ bool check_binary_op(CheckerContext *c, Operand *o, Token op) { error(op, "Operator '%.*s' is only allowed with integers", LIT(op.string)); return false; } - if (is_type_simd_vector(o->type)) { - switch (op.kind) { - case Token_ModMod: - case Token_ModModEq: - error(op, "Operator '%.*s' is only allowed with integers", LIT(op.string)); - return false; - } - } break; case Token_AndNot: @@ -1654,14 +1653,6 @@ bool check_binary_op(CheckerContext *c, Operand *o, Token op) { error(op, "Operator '%.*s' is only allowed with integers and bit sets", LIT(op.string)); return false; } - if (is_type_simd_vector(o->type)) { - switch (op.kind) { - case Token_AndNot: - case Token_AndNotEq: - error(op, "Operator '%.*s' is only allowed with integers", LIT(op.string)); - return false; - } - } break; case Token_CmpAnd: @@ -7738,6 +7729,7 @@ ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast *node, Type * } if (cl->elems.count > 0 && cl->elems[0]->kind == Ast_FieldValue) { + // TODO(bill): Why was this decision made for simd? if (is_type_simd_vector(t)) { error(cl->elems[0], "'field = value' is not allowed for SIMD vector literals"); } else { diff --git a/src/check_type.cpp b/src/check_type.cpp index 51f472961..193c42cde 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -2802,6 +2802,11 @@ bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_t *type = alloc_type_array(elem, count, generic_type); goto array_end; } + if (count < 1 || !is_power_of_two(count)) { + error(at->elem, "Invalid length for 'intrinsics.simd_vector', expected a power of two length, got '%lld'", cast(long long)count); + *type = alloc_type_array(elem, count, generic_type); + goto array_end; + } *type = alloc_type_simd_vector(count, elem); } else { diff --git a/src/common.cpp b/src/common.cpp index 94248fb62..77caddfe8 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -47,6 +47,13 @@ void debugf(char const *fmt, ...); #include "range_cache.cpp" +bool is_power_of_two(i64 x) { + if (x <= 0) { + return false; + } + return !(x & (x-1)); +} + int isize_cmp(isize x, isize y) { if (x < y) { return -1; diff --git a/src/types.cpp b/src/types.cpp index c79b8e652..d5ba1a531 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -3446,7 +3446,7 @@ i64 type_align_of_internal(Type *t, TypePath *path) { case Type_SimdVector: { // 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); + return gb_clamp(next_pow2(type_size_of_internal(t, path)), 1, build_context.max_align*2); } case Type_Matrix: