|
@@ -665,26 +665,40 @@ gb_internal bool check_builtin_simd_operation(CheckerContext *c, Operand *operan
|
|
|
|
|
|
case BuiltinProc_simd_gather:
|
|
|
case BuiltinProc_simd_scatter:
|
|
|
+ case BuiltinProc_simd_masked_load:
|
|
|
+ case BuiltinProc_simd_masked_store:
|
|
|
{
|
|
|
// gather (ptr: #simd[N]rawptr, values: #simd[N]T, mask: #simd[N]int_or_bool) -> #simd[N]T
|
|
|
// scatter(ptr: #simd[N]rawptr, values: #simd[N]T, mask: #simd[N]int_or_bool)
|
|
|
|
|
|
+ // masked_load (ptr: rawptr, values: #simd[N]T, mask: #simd[N]int_or_bool) -> #simd[N]T
|
|
|
+ // masked_store(ptr: rawptr, values: #simd[N]T, mask: #simd[N]int_or_bool)
|
|
|
+
|
|
|
Operand ptr = {};
|
|
|
Operand values = {};
|
|
|
Operand mask = {};
|
|
|
check_expr(c, &ptr, ce->args[0]); if (ptr.mode == Addressing_Invalid) return false;
|
|
|
check_expr(c, &values, ce->args[1]); if (values.mode == Addressing_Invalid) return false;
|
|
|
check_expr(c, &mask, ce->args[2]); if (mask.mode == Addressing_Invalid) return false;
|
|
|
- if (!is_type_simd_vector(ptr.type)) { error(ptr.expr, "'%.*s' expected a simd vector type", LIT(builtin_name)); return false; }
|
|
|
if (!is_type_simd_vector(values.type)) { error(values.expr, "'%.*s' expected a simd vector type", LIT(builtin_name)); return false; }
|
|
|
if (!is_type_simd_vector(mask.type)) { error(mask.expr, "'%.*s' expected a simd vector type", LIT(builtin_name)); return false; }
|
|
|
|
|
|
- Type *ptr_elem = base_array_type(ptr.type);
|
|
|
- if (!is_type_rawptr(ptr_elem)) {
|
|
|
- gbString s = type_to_string(ptr.type);
|
|
|
- error(ptr.expr, "Expected a simd vector of 'rawptr' for the addresses, got %s", s);
|
|
|
- gb_string_free(s);
|
|
|
- return false;
|
|
|
+ if (id == BuiltinProc_simd_gather || id == BuiltinProc_simd_scatter) {
|
|
|
+ if (!is_type_simd_vector(ptr.type)) { error(ptr.expr, "'%.*s' expected a simd vector type", LIT(builtin_name)); return false; }
|
|
|
+ Type *ptr_elem = base_array_type(ptr.type);
|
|
|
+ if (!is_type_rawptr(ptr_elem)) {
|
|
|
+ gbString s = type_to_string(ptr.type);
|
|
|
+ error(ptr.expr, "Expected a simd vector of 'rawptr' for the addresses, got %s", s);
|
|
|
+ gb_string_free(s);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (!is_type_pointer(ptr.type)) {
|
|
|
+ gbString s = type_to_string(ptr.type);
|
|
|
+ error(ptr.expr, "Expected a pointer type for the address, got %s", s);
|
|
|
+ gb_string_free(s);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
}
|
|
|
Type *mask_elem = base_array_type(mask.type);
|
|
|
|
|
@@ -695,19 +709,31 @@ gb_internal bool check_builtin_simd_operation(CheckerContext *c, Operand *operan
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- i64 ptr_count = get_array_type_count(ptr.type);
|
|
|
- i64 values_count = get_array_type_count(values.type);
|
|
|
- i64 mask_count = get_array_type_count(mask.type);
|
|
|
- if (ptr_count != values_count ||
|
|
|
- values_count != mask_count ||
|
|
|
- mask_count != ptr_count) {
|
|
|
- gbString s = type_to_string(mask.type);
|
|
|
- error(mask.expr, "All simd vectors must be of the same length, got %lld vs %lld vs %lld", cast(long long)ptr_count, cast(long long)values_count, cast(long long)mask_count);
|
|
|
- gb_string_free(s);
|
|
|
- return false;
|
|
|
+ if (id == BuiltinProc_simd_gather || id == BuiltinProc_simd_scatter) {
|
|
|
+ i64 ptr_count = get_array_type_count(ptr.type);
|
|
|
+ i64 values_count = get_array_type_count(values.type);
|
|
|
+ i64 mask_count = get_array_type_count(mask.type);
|
|
|
+ if (ptr_count != values_count ||
|
|
|
+ values_count != mask_count ||
|
|
|
+ mask_count != ptr_count) {
|
|
|
+ gbString s = type_to_string(mask.type);
|
|
|
+ error(mask.expr, "All simd vectors must be of the same length, got %lld vs %lld vs %lld", cast(long long)ptr_count, cast(long long)values_count, cast(long long)mask_count);
|
|
|
+ gb_string_free(s);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ i64 values_count = get_array_type_count(values.type);
|
|
|
+ i64 mask_count = get_array_type_count(mask.type);
|
|
|
+ if (values_count != mask_count) {
|
|
|
+ gbString s = type_to_string(mask.type);
|
|
|
+ error(mask.expr, "All simd vectors must be of the same length, got %lld vs %lld", cast(long long)values_count, cast(long long)mask_count);
|
|
|
+ gb_string_free(s);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- if (id == BuiltinProc_simd_gather) {
|
|
|
+ if (id == BuiltinProc_simd_gather ||
|
|
|
+ id == BuiltinProc_simd_masked_load) {
|
|
|
operand->mode = Addressing_Value;
|
|
|
operand->type = values.type;
|
|
|
} else {
|