aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2022-05-25 17:26:18 +0100
committergingerBill <bill@gingerbill.org>2022-05-25 17:26:18 +0100
commitb032d5af87ebe8d9dee28698cfa570d3628e58e5 (patch)
tree6d2f1a90d597a3909430c8a4c6002b1e586e76e7
parentd8e77cd738844b172d1741b1b1d3d4376efd17b5 (diff)
Make `#simd` an opaque type
-rw-r--r--src/check_decl.cpp20
-rw-r--r--src/check_expr.cpp24
-rw-r--r--src/check_type.cpp5
-rw-r--r--src/common.cpp7
-rw-r--r--src/types.cpp2
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: