Browse Source

Correct f64 -> u128/i128 generation

gingerBill 3 years ago
parent
commit
fa0d58f96e
4 changed files with 19 additions and 1 deletions
  1. 14 0
      core/runtime/internal.odin
  2. 2 0
      src/checker.cpp
  3. 1 1
      src/llvm_backend_expr.cpp
  4. 2 0
      src/types.cpp

+ 14 - 0
core/runtime/internal.odin

@@ -763,3 +763,17 @@ floattidf_unsigned :: proc(a: u128) -> f64 {
 	fb[1] = u32(a)                           // mantissa-low
 	return transmute(f64)fb
 }
+
+
+
+@(link_name="__fixunsdfti")
+fixunsdfti :: proc(a: f64) -> u128 {
+	x := u64(a)
+	return u128(x)
+}
+
+@(link_name="__fixunsdfdi")
+fixunsdfdi :: proc(a: f64) -> i128 {
+	x := i64(a)
+	return i128(x)
+}

+ 2 - 0
src/checker.cpp

@@ -1980,6 +1980,8 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) {
 		str_lit("modti3"),
 		str_lit("divti3"),
 		str_lit("fixdfti"),
+		str_lit("fixunsdfti"),
+		str_lit("fixunsdfdi"),
 		str_lit("floattidf"),
 		str_lit("floattidf_unsigned"),
 		str_lit("truncsfhf2"),

+ 1 - 1
src/llvm_backend_expr.cpp

@@ -1194,7 +1194,7 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
 			res = lb_emit_conv(p, value, platform_src_type);
 			res = lb_emit_conv(p, res, platform_dst_type);
 			if (is_type_different_to_arch_endianness(dst)) {
-				res = lb_emit_byte_swap(p, res, t);
+				res = lb_emit_byte_swap(p, res, platform_dst_type);
 			}
 			return lb_emit_conv(p, res, t);
 		}

+ 2 - 0
src/types.cpp

@@ -1518,6 +1518,7 @@ Type *integer_endian_type_to_platform_type(Type *t) {
 	case Basic_u32le: return t_u32;
 	case Basic_i64le: return t_i64;
 	case Basic_u64le: return t_u64;
+	case Basic_i128le: return t_i128;
 	case Basic_u128le: return t_u128;
 
 	case Basic_i16be: return t_i16;
@@ -1526,6 +1527,7 @@ Type *integer_endian_type_to_platform_type(Type *t) {
 	case Basic_u32be: return t_u32;
 	case Basic_i64be: return t_i64;
 	case Basic_u64be: return t_u64;
+	case Basic_i128be: return t_i128;
 	case Basic_u128be: return t_u128;
 
 	case Basic_f16le: return t_f16;