Browse Source

Fix conversion from float to quaternion

gingerBill 3 years ago
parent
commit
0d7cb02386
3 changed files with 16 additions and 25 deletions
  1. 2 2
      core/math/linalg/extended.odin
  2. 7 0
      src/check_expr.cpp
  3. 7 23
      src/llvm_backend_expr.cpp

+ 2 - 2
core/math/linalg/extended.odin

@@ -103,10 +103,10 @@ max :: proc{max_single, max_double, max_triple}
 abs :: proc(a: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
 	when IS_ARRAY(T) {
 		for i in 0..<len(T) {
-			out[i] = builtin.abs(a[i])
+			out[i] = auto_cast builtin.abs(a[i])
 		}
 	} else {
-		out = builtin.abs(a)
+		out = auto_cast builtin.abs(a)
 	}
 	return
 }

+ 7 - 0
src/check_expr.cpp

@@ -649,6 +649,13 @@ i64 check_distance_between_types(CheckerContext *c, Operand *operand, Type *type
 			return 4;
 		}
 	}
+	
+	if (is_type_complex_or_quaternion(dst)) {
+		Type *elem = base_complex_elem_type(dst);
+		if (are_types_identical(elem, base_type(src))) {
+			return 5;
+		}
+	}
 
 	if (is_type_array(dst)) {
 		Type *elem = base_array_type(dst);

+ 7 - 23
src/llvm_backend_expr.cpp

@@ -1655,26 +1655,10 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
 		return res;
 	}
 	
-	if (is_type_float(src) && is_type_complex(dst)) {
-		Type *ft = base_complex_elem_type(dst);
-		lbAddr gen = lb_add_local_generated(p, dst, false);
-		lbValue gp = lb_addr_get_ptr(p, gen);
-		lbValue real = lb_emit_conv(p, value, ft);
-		lb_emit_store(p, lb_emit_struct_ep(p, gp, 0), real);
-		return lb_addr_load(p, gen);
-	}
-	if (is_type_float(src) && is_type_quaternion(dst)) {
-		Type *ft = base_complex_elem_type(dst);
-		lbAddr gen = lb_add_local_generated(p, dst, false);
-		lbValue gp = lb_addr_get_ptr(p, gen);
-		lbValue real = lb_emit_conv(p, value, ft);
-		lb_emit_store(p, lb_emit_struct_ep(p, gp, 0), real);
-		return lb_addr_load(p, gen);
-	}
 
 	if (is_type_complex(src) && is_type_complex(dst)) {
 		Type *ft = base_complex_elem_type(dst);
-		lbAddr gen = lb_add_local_generated(p, dst, false);
+		lbAddr gen = lb_add_local_generated(p, t, false);
 		lbValue gp = lb_addr_get_ptr(p, gen);
 		lbValue real = lb_emit_conv(p, lb_emit_struct_ev(p, value, 0), ft);
 		lbValue imag = lb_emit_conv(p, lb_emit_struct_ev(p, value, 1), ft);
@@ -1686,7 +1670,7 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
 	if (is_type_quaternion(src) && is_type_quaternion(dst)) {
 		// @QuaternionLayout
 		Type *ft = base_complex_elem_type(dst);
-		lbAddr gen = lb_add_local_generated(p, dst, false);
+		lbAddr gen = lb_add_local_generated(p, t, false);
 		lbValue gp = lb_addr_get_ptr(p, gen);
 		lbValue q0 = lb_emit_conv(p, lb_emit_struct_ev(p, value, 0), ft);
 		lbValue q1 = lb_emit_conv(p, lb_emit_struct_ev(p, value, 1), ft);
@@ -1701,7 +1685,7 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
 
 	if (is_type_integer(src) && is_type_complex(dst)) {
 		Type *ft = base_complex_elem_type(dst);
-		lbAddr gen = lb_add_local_generated(p, dst, true);
+		lbAddr gen = lb_add_local_generated(p, t, true);
 		lbValue gp = lb_addr_get_ptr(p, gen);
 		lbValue real = lb_emit_conv(p, value, ft);
 		lb_emit_store(p, lb_emit_struct_ep(p, gp, 0), real);
@@ -1709,7 +1693,7 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
 	}
 	if (is_type_float(src) && is_type_complex(dst)) {
 		Type *ft = base_complex_elem_type(dst);
-		lbAddr gen = lb_add_local_generated(p, dst, true);
+		lbAddr gen = lb_add_local_generated(p, t, true);
 		lbValue gp = lb_addr_get_ptr(p, gen);
 		lbValue real = lb_emit_conv(p, value, ft);
 		lb_emit_store(p, lb_emit_struct_ep(p, gp, 0), real);
@@ -1719,7 +1703,7 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
 
 	if (is_type_integer(src) && is_type_quaternion(dst)) {
 		Type *ft = base_complex_elem_type(dst);
-		lbAddr gen = lb_add_local_generated(p, dst, true);
+		lbAddr gen = lb_add_local_generated(p, t, true);
 		lbValue gp = lb_addr_get_ptr(p, gen);
 		lbValue real = lb_emit_conv(p, value, ft);
 		// @QuaternionLayout
@@ -1728,7 +1712,7 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
 	}
 	if (is_type_float(src) && is_type_quaternion(dst)) {
 		Type *ft = base_complex_elem_type(dst);
-		lbAddr gen = lb_add_local_generated(p, dst, true);
+		lbAddr gen = lb_add_local_generated(p, t, true);
 		lbValue gp = lb_addr_get_ptr(p, gen);
 		lbValue real = lb_emit_conv(p, value, ft);
 		// @QuaternionLayout
@@ -1737,7 +1721,7 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
 	}
 	if (is_type_complex(src) && is_type_quaternion(dst)) {
 		Type *ft = base_complex_elem_type(dst);
-		lbAddr gen = lb_add_local_generated(p, dst, true);
+		lbAddr gen = lb_add_local_generated(p, t, true);
 		lbValue gp = lb_addr_get_ptr(p, gen);
 		lbValue real = lb_emit_conv(p, lb_emit_struct_ev(p, value, 0), ft);
 		lbValue imag = lb_emit_conv(p, lb_emit_struct_ev(p, value, 1), ft);