From bebd5ac0d7732f9efc28bf2714006080ab52ec3a Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Sat, 16 Oct 2021 16:42:40 -0500 Subject: [PATCH] starting to implement threading on the browser --- core/intrinsics/atomics.onyx | 26 ++++++++++++++++++++++++++ core/std.onyx | 4 ++++ include/astnodes.h | 15 +++++++++++++++ include/wasm.h | 6 ++++-- src/builtins.c | 15 +++++++++++++++ src/wasm_intrinsics.c | 36 ++++++++++++++++++++++++++++++++++++ src/wasm_output.c | 5 +++++ 7 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 core/intrinsics/atomics.onyx diff --git a/core/intrinsics/atomics.onyx b/core/intrinsics/atomics.onyx new file mode 100644 index 00000000..30a41bcc --- /dev/null +++ b/core/intrinsics/atomics.onyx @@ -0,0 +1,26 @@ +package core.intrinsics.atomics + +#private_file { + runtime :: package Runtime + + #if !#defined(runtime.Allow_Multi_Threading) { + #error "Multi-threading is not enabled so you cannot include the 'core.intrinsics.atomics' package." + } +} + +// __atomic_wait is only valid for i32 and i64 +__atomic_wait :: (addr: ^$T, value: T, timeout: i64 = 0) -> i32 #intrinsic --- +__atomic_notify :: (addr: rawptr, maximum: i32 = 1) -> i32 #intrinsic --- + +__atomic_fence :: () -> void #intrinsic --- + +// These are only valid for the eight integer types (i8, u8, i16, u16, i32, u32, i64, u64) +__atomic_load :: (addr: ^$T) -> T #intrinsic --- +__atomic_store :: (addr: ^$T, value: T) -> void #intrinsic --- +__atomic_add :: (addr: ^$T, value: T) -> T #intrinsic --- +__atomic_sub :: (addr: ^$T, value: T) -> T #intrinsic --- +__atomic_and :: (addr: ^$T, value: T) -> T #intrinsic --- +__atomic_or :: (addr: ^$T, value: T) -> T #intrinsic --- +__atomic_xor :: (addr: ^$T, value: T) -> T #intrinsic --- +__atomic_xchg :: (addr: ^$T, value: T) -> T #intrinsic --- +__atomic_cmpxchg :: (addr: ^$T, compare: T, value: T) -> T #intrinsic --- diff --git a/core/std.onyx b/core/std.onyx index ba6f91a0..43602d9d 100644 --- a/core/std.onyx +++ b/core/std.onyx @@ -52,3 +52,7 @@ package core #if runtime.Runtime != runtime.Runtime_Custom { #load "./stdio" } + +#if #defined(runtime.Allow_Multi_Threading) { + #load "./intrinsics/atomics" +} \ No newline at end of file diff --git a/include/astnodes.h b/include/astnodes.h index 20966dd9..78b4b570 100644 --- a/include/astnodes.h +++ b/include/astnodes.h @@ -457,6 +457,21 @@ typedef enum OnyxIntrinsic { ONYX_INTRINSIC_I32X4_TRUNC_SAT_F32X4_U, ONYX_INTRINSIC_F32X4_CONVERT_I32X4_S, ONYX_INTRINSIC_F32X4_CONVERT_I32X4_U, + + ONYX_INTRINSIC_ATOMIC_WAIT, + ONYX_INTRINSIC_ATOMIC_NOTIFY, + + ONYX_INTRINSIC_ATOMIC_FENCE, + + ONYX_INTRINSIC_ATOMIC_LOAD, + ONYX_INTRINSIC_ATOMIC_STORE, + ONYX_INTRINSIC_ATOMIC_ADD, + ONYX_INTRINSIC_ATOMIC_SUB, + ONYX_INTRINSIC_ATOMIC_AND, + ONYX_INTRINSIC_ATOMIC_OR, + ONYX_INTRINSIC_ATOMIC_XOR, + ONYX_INTRINSIC_ATOMIC_XCHG, + ONYX_INTRINSIC_ATOMIC_CMPXCHG, } OnyxIntrinsic; typedef enum CallingConvention { diff --git a/include/wasm.h b/include/wasm.h index 7d0ddc30..d09f7da8 100644 --- a/include/wasm.h +++ b/include/wasm.h @@ -16,8 +16,9 @@ typedef struct WasmFuncType { WasmType param_types[]; } WasmFuncType; -#define SIMD_INSTR_MASK 0x10000 -#define EXT_INSTR_MASK 0x20000 +#define SIMD_INSTR_MASK 0x10000 +#define EXT_INSTR_MASK 0x20000 +#define ATOMIC_INSTR_MASK 0x40000 typedef enum WasmInstructionType { WI_UNREACHABLE = 0x00, @@ -425,6 +426,7 @@ typedef enum WasmInstructionType { WI_MEMORY_COPY = EXT_INSTR_MASK | 0x0a, WI_MEMORY_FILL = EXT_INSTR_MASK | 0x0b, + } WasmInstructionType; typedef union { diff --git a/src/builtins.c b/src/builtins.c index 511effa6..f70ea09b 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -332,6 +332,21 @@ static IntrinsicMap builtin_intrinsics[] = { { "f32x4_convert_i32x4_s", ONYX_INTRINSIC_F32X4_CONVERT_I32X4_S }, { "f32x4_convert_i32x4_u", ONYX_INTRINSIC_F32X4_CONVERT_I32X4_U }, + { "__atomic_wait", ONYX_INTRINSIC_ATOMIC_WAIT }, + { "__atomic_notify", ONYX_INTRINSIC_ATOMIC_NOTIFY }, + + { "__atomic_fence", ONYX_INTRINSIC_ATOMIC_FENCE }, + + { "__atomic_load", ONYX_INTRINSIC_ATOMIC_LOAD }, + { "__atomic_store", ONYX_INTRINSIC_ATOMIC_STORE }, + { "__atomic_add", ONYX_INTRINSIC_ATOMIC_ADD }, + { "__atomic_sub", ONYX_INTRINSIC_ATOMIC_SUB }, + { "__atomic_and", ONYX_INTRINSIC_ATOMIC_AND }, + { "__atomic_or", ONYX_INTRINSIC_ATOMIC_OR }, + { "__atomic_xor", ONYX_INTRINSIC_ATOMIC_XOR }, + { "__atomic_xchg", ONYX_INTRINSIC_ATOMIC_XCHG }, + { "__atomic_cmpxchg", ONYX_INTRINSIC_ATOMIC_CMPXCHG }, + { NULL, ONYX_INTRINSIC_UNDEFINED }, }; diff --git a/src/wasm_intrinsics.c b/src/wasm_intrinsics.c index b39fad86..e61192b6 100644 --- a/src/wasm_intrinsics.c +++ b/src/wasm_intrinsics.c @@ -151,3 +151,39 @@ EMIT_FUNC(initialize_type, Type* type, OnyxToken* where) { *pcode = code; } + +EMIT_FUNC(intrinsic_atomic_wait, Type* type, OnyxToken* where) { +} + +EMIT_FUNC(intrinsic_atomic_notify, Type* type, OnyxToken* where) { +} + +EMIT_FUNC_NO_ARGS(intrinsic_atomic_fence) { +} + +EMIT_FUNC(intrinsic_atomic_load, Type* type, OnyxToken* where) { +} + +EMIT_FUNC(intrinsic_atomic_store, Type* type, OnyxToken* where) { +} + +EMIT_FUNC(intrinsic_atomic_add, Type* type, OnyxToken* where) { +} + +EMIT_FUNC(intrinsic_atomic_sub, Type* type, OnyxToken* where) { +} + +EMIT_FUNC(intrinsic_atomic_and, Type* type, OnyxToken* where) { +} + +EMIT_FUNC(intrinsic_atomic_or, Type* type, OnyxToken* where) { +} + +EMIT_FUNC(intrinsic_atomic_xor, Type* type, OnyxToken* where) { +} + +EMIT_FUNC(intrinsic_atomic_xchg, Type* type, OnyxToken* where) { +} + +EMIT_FUNC(intrinsic_atomic_cmpxchg, Type* type, OnyxToken* where) { +} diff --git a/src/wasm_output.c b/src/wasm_output.c index e1c57645..8ab0598d 100644 --- a/src/wasm_output.c +++ b/src/wasm_output.c @@ -406,6 +406,11 @@ static void output_instruction(WasmFunc* func, WasmInstruction* instr, bh_buffer bh_buffer_write_byte(buff, 0xFC); leb = uint_to_uleb128((u64) (instr->type &~ EXT_INSTR_MASK), &leb_len); bh_buffer_append(buff, leb, leb_len); + + } else if (instr->type & ATOMIC_INSTR_MASK) { + bh_buffer_write_byte(buff, 0xFE); + leb = uint_to_uleb128((u64) (instr->type &~ ATOMIC_INSTR_MASK), &leb_len); + bh_buffer_append(buff, leb, leb_len); } else { bh_buffer_write_byte(buff, (u8) instr->type); -- 2.25.1