Browse Source

Fix 128-bit integer support for wasm targets

gingerBill 11 months ago
parent
commit
b116e8ff55
3 changed files with 51 additions and 24 deletions
  1. 41 19
      base/runtime/procs_wasm.odin
  2. 5 4
      src/llvm_abi.cpp
  3. 5 1
      vendor/wasm/js/events.odin

+ 41 - 19
base/runtime/procs_wasm.odin

@@ -14,33 +14,57 @@ ti_uint :: struct #raw_union {
 }
 }
 
 
 @(link_name="__ashlti3", linkage="strong")
 @(link_name="__ashlti3", linkage="strong")
-__ashlti3 :: proc "contextless" (la, ha: u64, b_: u32) -> i128 {
-	bits_in_dword :: size_of(u32)*8
-	b := u32(b_)
+__ashlti3 :: proc "contextless" (a: i128, b: u32) -> i128 {
+	bits :: 64
 	
 	
-	input, result: ti_int
-	input.lo, input.hi = la, ha
-	if b & bits_in_dword != 0 {
+	input: ti_int = ---
+	result: ti_int = ---
+	input.all = a
+	if b & bits != 0 {
 		result.lo = 0
 		result.lo = 0
-		result.hi = input.lo << (b-bits_in_dword)
+		result.hi = input.lo << (b-bits)
 	} else {
 	} else {
 		if b == 0 {
 		if b == 0 {
-			return input.all
+			return a
 		}
 		}
 		result.lo = input.lo<<b
 		result.lo = input.lo<<b
-		result.hi = (input.hi<<b) | (input.lo>>(bits_in_dword-b))
+		result.hi = (input.hi<<b) | (input.lo>>(bits-b))
 	}
 	}
 	return result.all
 	return result.all
 }
 }
 
 
+__ashlti3_unsigned :: proc "contextless" (a: u128, b: u32) -> u128 {
+	return cast(u128)__ashlti3(cast(i128)a, b)
+}
+
+@(link_name="__mulddi3", linkage="strong")
+__mulddi3 :: proc "contextless" (a, b: u64) -> i128 {
+	r: ti_int
+	bits :: 32
+
+	mask :: ~u64(0) >> bits
+	r.lo = (a & mask) * (b & mask)
+	t := r.lo >> bits
+	r.lo &= mask
+	t += (a >> bits) * (b & mask)
+	r.lo += (t & mask) << bits
+	r.hi = t >> bits
+	t = r.lo >> bits
+	r.lo &= mask
+	t += (b >> bits) * (a & mask)
+	r.lo += (t & mask) << bits
+	r.hi += t >> bits
+	r.hi += (a >> bits) * (b >> bits)
+	return r.all
+}
 
 
 @(link_name="__multi3", linkage="strong")
 @(link_name="__multi3", linkage="strong")
-__multi3 :: proc "contextless" (la, ha, lb, hb: u64) -> i128 {
+__multi3 :: proc "contextless" (a, b: i128) -> i128 {
 	x, y, r: ti_int
 	x, y, r: ti_int
 
 
-	x.lo, x.hi = la, ha
-	y.lo, y.hi = lb, hb
-	r.all = i128(x.lo * y.lo) // TODO this is incorrect
+	x.all = a
+	y.all = b
+	r.all = __mulddi3(x.lo, y.lo)
 	r.hi += x.hi*y.lo + x.lo*y.hi
 	r.hi += x.hi*y.lo + x.lo*y.hi
 	return r.all
 	return r.all
 }
 }
@@ -54,18 +78,16 @@ udivti3 :: proc "c" (la, ha, lb, hb: u64) -> u128 {
 }
 }
 
 
 @(link_name="__lshrti3", linkage="strong")
 @(link_name="__lshrti3", linkage="strong")
-__lshrti3 :: proc "c" (la, ha: u64, b: u32) -> i128 {
-	bits :: size_of(u32)*8
+__lshrti3 :: proc "c" (a: i128, b: u32) -> i128 {
+	bits :: 64
 
 
 	input, result: ti_int
 	input, result: ti_int
-	input.lo = la
-	input.hi = ha
-
+	input.all = a
 	if b & bits != 0 {
 	if b & bits != 0 {
 		result.hi = 0
 		result.hi = 0
 		result.lo = input.hi >> (b - bits)
 		result.lo = input.hi >> (b - bits)
 	} else if b == 0 {
 	} else if b == 0 {
-		return input.all
+		return a
 	} else {
 	} else {
 		result.hi = input.hi >> b
 		result.hi = input.hi >> b
 		result.lo = (input.hi << (bits - b)) | (input.lo >> b)
 		result.lo = (input.hi << (bits - b)) | (input.lo >> b)

+ 5 - 4
src/llvm_abi.cpp

@@ -1257,11 +1257,12 @@ namespace lbAbiWasm {
 	}
 	}
 
 
 	gb_internal lbArgType non_struct(LLVMContextRef c, LLVMTypeRef type, bool is_return) {
 	gb_internal lbArgType non_struct(LLVMContextRef c, LLVMTypeRef type, bool is_return) {
-		if (!is_return && type == LLVMIntTypeInContext(c, 128)) {
-			LLVMTypeRef cast_type = LLVMVectorType(LLVMInt64TypeInContext(c), 2);
+		if (type == LLVMIntTypeInContext(c, 128)) {
+			// LLVMTypeRef cast_type = LLVMVectorType(LLVMInt64TypeInContext(c), 2);
+			LLVMTypeRef cast_type = nullptr;
 			return lb_arg_type_direct(type, cast_type, nullptr, nullptr);
 			return lb_arg_type_direct(type, cast_type, nullptr, nullptr);
 		}
 		}
-		
+
 		if (!is_return && lb_sizeof(type) > 8) {
 		if (!is_return && lb_sizeof(type) > 8) {
 			return lb_arg_type_indirect(type, nullptr);
 			return lb_arg_type_indirect(type, nullptr);
 		}
 		}
@@ -1282,7 +1283,7 @@ namespace lbAbiWasm {
 		case LLVMPointerTypeKind:
 		case LLVMPointerTypeKind:
 			return true;
 			return true;
 		case LLVMIntegerTypeKind:
 		case LLVMIntegerTypeKind:
-			return lb_sizeof(type) <= 8;
+			return lb_sizeof(type) <= 16;
 		}	
 		}	
 		return false;
 		return false;
 	}
 	}

+ 5 - 1
vendor/wasm/js/events.odin

@@ -30,6 +30,8 @@ Event_Kind :: enum u32 {
 	Wheel,
 	Wheel,
 
 
 	Focus,
 	Focus,
+	Focus_In,
+	Focus_Out,
 	Submit,
 	Submit,
 	Blur,
 	Blur,
 	Change,
 	Change,
@@ -110,6 +112,8 @@ event_kind_string := [Event_Kind]string{
 	.Wheel = "wheel",
 	.Wheel = "wheel",
 
 
 	.Focus        = "focus",
 	.Focus        = "focus",
+	.Focus_In     = "focusin",
+	.Focus_Out    = "focusout",
 	.Submit       = "submit",
 	.Submit       = "submit",
 	.Blur         = "blur",
 	.Blur         = "blur",
 	.Change       = "change",
 	.Change       = "change",
@@ -332,7 +336,7 @@ remove_custom_event_listener :: proc(id: string, name: string, user_data: rawptr
 	return _remove_event_listener(id, name, user_data, callback)
 	return _remove_event_listener(id, name, user_data, callback)
 }
 }
 
 
-
+import "core:fmt"
 
 
 
 
 @(export, link_name="odin_dom_do_event_callback")
 @(export, link_name="odin_dom_do_event_callback")