Browse Source

Make `#simd` an opaque type

gingerBill 3 years ago
parent
commit
b032d5af87
5 changed files with 34 additions and 24 deletions
  1. 13 7
      src/check_decl.cpp
  2. 8 16
      src/check_expr.cpp
  3. 5 0
      src/check_type.cpp
  4. 7 0
      src/common.cpp
  5. 1 1
      src/types.cpp

+ 13 - 7
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;
 	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) {
 	if (!is_distinct) {
 		e->type = bt;
 		e->type = bt;

+ 8 - 16
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) {
 bool check_binary_op(CheckerContext *c, Operand *o, Token op) {
 	Type *main_type = o->type;
 	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
 	// TODO(bill): Handle errors correctly
 	Type *type = base_type(core_array_type(main_type));
 	Type *type = base_type(core_array_type(main_type));
 	Type *ct = core_type(type);
 	Type *ct = core_type(type);
+
 	switch (op.kind) {
 	switch (op.kind) {
 	case Token_Sub:
 	case Token_Sub:
 	case Token_SubEq:
 	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));
 			error(op, "Operator '%.*s' is only allowed with integers", LIT(op.string));
 			return false;
 			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;
 		break;
 
 
 	case Token_AndNot:
 	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));
 			error(op, "Operator '%.*s' is only allowed with integers and bit sets", LIT(op.string));
 			return false;
 			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;
 		break;
 
 
 	case Token_CmpAnd:
 	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) {
 		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)) {
 			if (is_type_simd_vector(t)) {
 				error(cl->elems[0], "'field = value' is not allowed for SIMD vector literals");
 				error(cl->elems[0], "'field = value' is not allowed for SIMD vector literals");
 			} else {
 			} else {

+ 5 - 0
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);
 						*type = alloc_type_array(elem, count, generic_type);
 						goto array_end;
 						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);
 					*type = alloc_type_simd_vector(count, elem);
 				} else {
 				} else {

+ 7 - 0
src/common.cpp

@@ -47,6 +47,13 @@ void debugf(char const *fmt, ...);
 #include "range_cache.cpp"
 #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) {
 int isize_cmp(isize x, isize y) {
 	if (x < y) {
 	if (x < y) {
 		return -1;
 		return -1;

+ 1 - 1
src/types.cpp

@@ -3446,7 +3446,7 @@ i64 type_align_of_internal(Type *t, TypePath *path) {
 
 
 	case Type_SimdVector: {
 	case Type_SimdVector: {
 		// IMPORTANT TODO(bill): Figure out the alignment of vector types
 		// 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: 
 	case Type_Matrix: