aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2022-05-26 14:51:50 +0100
committergingerBill <bill@gingerbill.org>2022-05-26 14:51:50 +0100
commitf308f37ba112ca361715e470d513749236da026d (patch)
tree1dd9053ed9b29b018b04ee244dd07422db1be39f /src
parentc2610cb75ed81d687a4e6962283f498e94773706 (diff)
Remove need for `simd.splat`
Diffstat (limited to 'src')
-rw-r--r--src/check_expr.cpp8
-rw-r--r--src/llvm_backend_const.cpp26
-rw-r--r--src/llvm_backend_expr.cpp72
3 files changed, 74 insertions, 32 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index fcd7818bc..2a3b5bf02 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -2713,6 +2713,14 @@ bool check_is_castable_to(CheckerContext *c, Operand *operand, Type *y) {
return check_is_castable_to(c, &x, elem_dst);
}
+ if (is_type_simd_vector(dst)) {
+ Type *elem = base_array_type(dst);
+ if (check_is_castable_to(c, operand, elem)) {
+ return true;
+ }
+ }
+
+
return false;
}
diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp
index 3a3067dbc..bd76400de 100644
--- a/src/llvm_backend_const.cpp
+++ b/src/llvm_backend_const.cpp
@@ -495,9 +495,9 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
res.value = data;
return res;
} else if (is_type_array(type) &&
- value.kind != ExactValue_Invalid &&
- value.kind != ExactValue_String &&
- value.kind != ExactValue_Compound) {
+ value.kind != ExactValue_Invalid &&
+ value.kind != ExactValue_String &&
+ value.kind != ExactValue_Compound) {
i64 count = type->Array.count;
Type *elem = type->Array.elem;
@@ -513,8 +513,8 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
res.value = llvm_const_array(lb_type(m, elem), elems, cast(unsigned)count);
return res;
} else if (is_type_matrix(type) &&
- value.kind != ExactValue_Invalid &&
- value.kind != ExactValue_Compound) {
+ value.kind != ExactValue_Invalid &&
+ value.kind != ExactValue_Compound) {
i64 row = type->Matrix.row_count;
i64 column = type->Matrix.column_count;
GB_ASSERT(row == column);
@@ -537,6 +537,22 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
res.value = LLVMConstArray(lb_type(m, elem), elems, cast(unsigned)total_elem_count);
return res;
+ } else if (is_type_simd_vector(type) &&
+ value.kind != ExactValue_Invalid &&
+ value.kind != ExactValue_Compound) {
+ i64 count = type->SimdVector.count;
+ Type *elem = type->SimdVector.elem;
+
+ lbValue single_elem = lb_const_value(m, elem, value, allow_local);
+ single_elem.value = llvm_const_cast(single_elem.value, lb_type(m, elem));
+
+ LLVMValueRef *elems = gb_alloc_array(permanent_allocator(), LLVMValueRef, count);
+ for (i64 i = 0; i < count; i++) {
+ elems[i] = single_elem.value;
+ }
+
+ res.value = LLVMConstVector(elems, cast(unsigned)count);
+ return res;
}
switch (value.kind) {
diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp
index 426becc1c..10c337650 100644
--- a/src/llvm_backend_expr.cpp
+++ b/src/llvm_backend_expr.cpp
@@ -1820,41 +1820,59 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
return res;
}
- if (is_type_simd_vector(src) && is_type_simd_vector(dst)) {
- Type *src_elem = core_array_type(src);
- Type *dst_elem = core_array_type(dst);
+ if (is_type_simd_vector(dst)) {
+ Type *et = base_array_type(dst);
+ if (is_type_simd_vector(src)) {
+ Type *src_elem = core_array_type(src);
+ Type *dst_elem = core_array_type(dst);
- GB_ASSERT(src->SimdVector.count == dst->SimdVector.count);
+ GB_ASSERT(src->SimdVector.count == dst->SimdVector.count);
- lbValue res = {};
- res.type = t;
- if (are_types_identical(src_elem, dst_elem)) {
- res.value = value.value;
- } else if (is_type_float(src_elem) && is_type_integer(dst_elem)) {
- if (is_type_unsigned(dst_elem)) {
- res.value = LLVMBuildFPToUI(p->builder, value.value, lb_type(m, t), "");
- } else {
- res.value = LLVMBuildFPToSI(p->builder, value.value, lb_type(m, t), "");
- }
- } else if (is_type_integer(src_elem) && is_type_float(dst_elem)) {
- if (is_type_unsigned(src_elem)) {
- res.value = LLVMBuildUIToFP(p->builder, value.value, lb_type(m, t), "");
+ lbValue res = {};
+ res.type = t;
+ if (are_types_identical(src_elem, dst_elem)) {
+ res.value = value.value;
+ } else if (is_type_float(src_elem) && is_type_integer(dst_elem)) {
+ if (is_type_unsigned(dst_elem)) {
+ res.value = LLVMBuildFPToUI(p->builder, value.value, lb_type(m, t), "");
+ } else {
+ res.value = LLVMBuildFPToSI(p->builder, value.value, lb_type(m, t), "");
+ }
+ } else if (is_type_integer(src_elem) && is_type_float(dst_elem)) {
+ if (is_type_unsigned(src_elem)) {
+ res.value = LLVMBuildUIToFP(p->builder, value.value, lb_type(m, t), "");
+ } else {
+ res.value = LLVMBuildSIToFP(p->builder, value.value, lb_type(m, t), "");
+ }
+ } else if ((is_type_integer(src_elem) || is_type_boolean(src_elem)) && is_type_integer(dst_elem)) {
+ res.value = LLVMBuildIntCast2(p->builder, value.value, lb_type(m, t), !is_type_unsigned(src_elem), "");
+ } else if (is_type_float(src_elem) && is_type_float(dst_elem)) {
+ res.value = LLVMBuildFPCast(p->builder, value.value, lb_type(m, t), "");
+ } else if (is_type_integer(src_elem) && is_type_boolean(dst_elem)) {
+ LLVMValueRef i1vector = LLVMBuildICmp(p->builder, LLVMIntNE, value.value, LLVMConstNull(LLVMTypeOf(value.value)), "");
+ res.value = LLVMBuildIntCast2(p->builder, i1vector, lb_type(m, t), !is_type_unsigned(src_elem), "");
} else {
- res.value = LLVMBuildSIToFP(p->builder, value.value, lb_type(m, t), "");
+ GB_PANIC("Unhandled simd vector conversion: %s -> %s", type_to_string(src), type_to_string(dst));
}
- } else if ((is_type_integer(src_elem) || is_type_boolean(src_elem)) && is_type_integer(dst_elem)) {
- res.value = LLVMBuildIntCast2(p->builder, value.value, lb_type(m, t), !is_type_unsigned(src_elem), "");
- } else if (is_type_float(src_elem) && is_type_float(dst_elem)) {
- res.value = LLVMBuildFPCast(p->builder, value.value, lb_type(m, t), "");
- } else if (is_type_integer(src_elem) && is_type_boolean(dst_elem)) {
- LLVMValueRef i1vector = LLVMBuildICmp(p->builder, LLVMIntNE, value.value, LLVMConstNull(LLVMTypeOf(value.value)), "");
- res.value = LLVMBuildIntCast2(p->builder, i1vector, lb_type(m, t), !is_type_unsigned(src_elem), "");
+ return res;
} else {
- GB_PANIC("Unhandled simd vector conversion: %s -> %s", type_to_string(src), type_to_string(dst));
+ i64 count = get_array_type_count(dst);
+ LLVMTypeRef vt = lb_type(m, t);
+ LLVMTypeRef llvm_u32 = lb_type(m, t_u32);
+ LLVMValueRef elem = lb_emit_conv(p, value, et).value;
+ LLVMValueRef vector = LLVMConstNull(vt);
+ for (i64 i = 0; i < count; i++) {
+ LLVMValueRef idx = LLVMConstInt(llvm_u32, i, false);
+ vector = LLVMBuildInsertElement(p->builder, vector, elem, idx, "");
+ }
+ lbValue res = {};
+ res.type = t;
+ res.value = vector;
+ return res;
}
- return res;
}
+
// Pointer <-> uintptr
if (is_type_pointer(src) && is_type_uintptr(dst)) {
lbValue res = {};