From: Brendan Hansen Date: Wed, 9 Sep 2020 13:30:25 +0000 (-0500) Subject: added 'simd' package with simd types X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=29d9657051e58a864417f383a40dea46c5e58586;p=onyx.git added 'simd' package with simd types --- diff --git a/.vimspector.json b/.vimspector.json index bf221152..5cd4edea 100644 --- a/.vimspector.json +++ b/.vimspector.json @@ -6,7 +6,7 @@ "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/onyx", - "args": ["-verbose", "progs/odin_example.onyx"], + "args": ["-verbose", "progs/simd_test.onyx"], "stopAtEntry": true, "cwd": "${workspaceFolder}", "environment": [], diff --git a/Makefile b/Makefile index 8754d4ee..4778e4be 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -RELEASE=1 +RELEASE=0 OBJ_FILES=\ build/onyxlex.o \ diff --git a/include/onyxtypes.h b/include/onyxtypes.h index 5dfe489a..7f985237 100644 --- a/include/onyxtypes.h +++ b/include/onyxtypes.h @@ -21,6 +21,13 @@ enum BasicKind { Basic_Kind_F64, Basic_Kind_Rawptr, + + Basic_Kind_I8X16, + Basic_Kind_I16X8, + Basic_Kind_I32X4, + Basic_Kind_I64X2, + Basic_Kind_F32X4, + Basic_Kind_F64X2, }; enum BasicFlag { @@ -30,6 +37,8 @@ enum BasicFlag { Basic_Flag_Float = BH_BIT(3), Basic_Flag_Pointer = BH_BIT(4), + Basic_Flag_SIMD = BH_BIT(5), + Basic_Flag_Numeric = Basic_Flag_Integer | Basic_Flag_Float, Basic_Flag_Ordered = Basic_Flag_Integer | Basic_Flag_Float | Basic_Flag_Pointer, Basic_Flag_Constant_Type = Basic_Flag_Boolean | Basic_Flag_Numeric | Basic_Flag_Pointer, diff --git a/include/onyxwasm.h b/include/onyxwasm.h index 4c3e6ea7..2328a04d 100644 --- a/include/onyxwasm.h +++ b/include/onyxwasm.h @@ -8,11 +8,6 @@ typedef u8 WasmType; -extern const WasmType WASM_TYPE_INT32; -extern const WasmType WASM_TYPE_INT64; -extern const WasmType WASM_TYPE_FLOAT32; -extern const WasmType WASM_TYPE_FLOAT64; - typedef struct WasmFuncType { // NOTE: For now, WASM only allows for 1 return value. // This may be lifted in the future. @@ -246,15 +241,15 @@ typedef struct WasmInstruction { typedef struct BranchTable { u32 count; u32 default_case; - u32 cases[]; + u32 cases[]; } BranchTable; #define LOCAL_IS_WASM 0x8000000000000 typedef struct LocalAllocator { u32 param_count; - u32 allocated[4]; - u32 freed[4]; + u32 allocated[5]; + u32 freed[5]; i32 max_stack; i32 curr_stack; diff --git a/misc/onyx.sublime-syntax b/misc/onyx.sublime-syntax index 6d0bbfcd..5bbabea6 100644 --- a/misc/onyx.sublime-syntax +++ b/misc/onyx.sublime-syntax @@ -32,6 +32,9 @@ contexts: - match: '\b(bool|void|i8|u8|i16|u16|i32|u32|i64|u64|f32|f64|rawptr)\b' scope: keyword.control.onyx + - match: '\b(i8x16|i16x8|i32x4|i64x2|f32x4|f64x2)\b' + scope: keyword.control.onyx + - match: '\b(true|false|null|context)\b' scope: constant.numeric.onyx @@ -63,4 +66,4 @@ contexts: - match: '\*/' pop: true - match: '/\*' - push: block_comment \ No newline at end of file + push: block_comment diff --git a/misc/onyx.vim b/misc/onyx.vim index e037825f..99bea6e5 100644 --- a/misc/onyx.vim +++ b/misc/onyx.vim @@ -25,6 +25,12 @@ syn keyword onyxType i64 u64 syn keyword onyxType f32 syn keyword onyxType f64 syn keyword onyxType rawptr +syn keyword onyxType i8x16 +syn keyword onyxType i16x8 +syn keyword onyxType i32x4 +syn keyword onyxType i64x2 +syn keyword onyxType f32x4 +syn keyword onyxType f64x2 syn keyword onyxConstant true false null diff --git a/onyx b/onyx index a68a99c1..0a728275 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/simd_test.onyx b/progs/simd_test.onyx new file mode 100644 index 00000000..cf59c925 --- /dev/null +++ b/progs/simd_test.onyx @@ -0,0 +1,10 @@ +package main + +#include_file "core/std/wasi" + +use package core +use package simd + +main :: proc (args: [] cstring) { + x : i32x4; +} diff --git a/src/onyxbuiltins.c b/src/onyxbuiltins.c index 6362331e..fa1bb321 100644 --- a/src/onyxbuiltins.c +++ b/src/onyxbuiltins.c @@ -17,6 +17,14 @@ AstBasicType basic_type_f32 = { Ast_Kind_Basic_Type, 0, NULL, "f32" , &basi AstBasicType basic_type_f64 = { Ast_Kind_Basic_Type, 0, NULL, "f64" , &basic_types[Basic_Kind_F64] }; AstBasicType basic_type_rawptr = { Ast_Kind_Basic_Type, 0, NULL, "rawptr", &basic_types[Basic_Kind_Rawptr] }; +static OnyxToken simd_token = { Token_Type_Symbol, 14, "simd intrinsic", { 0 } }; +AstBasicType basic_type_i8x16 = { Ast_Kind_Basic_Type, 0, &simd_token, "i8x16", &basic_types[Basic_Kind_I8X16] }; +AstBasicType basic_type_i16x8 = { Ast_Kind_Basic_Type, 0, &simd_token, "i16x8", &basic_types[Basic_Kind_I16X8] }; +AstBasicType basic_type_i32x4 = { Ast_Kind_Basic_Type, 0, &simd_token, "i32x4", &basic_types[Basic_Kind_I32X4] }; +AstBasicType basic_type_i64x2 = { Ast_Kind_Basic_Type, 0, &simd_token, "i64x2", &basic_types[Basic_Kind_I64X2] }; +AstBasicType basic_type_f32x4 = { Ast_Kind_Basic_Type, 0, &simd_token, "f32x4", &basic_types[Basic_Kind_F32X4] }; +AstBasicType basic_type_f64x2 = { Ast_Kind_Basic_Type, 0, &simd_token, "f64x2", &basic_types[Basic_Kind_F64X2] }; + static OnyxToken builtin_package_token = { Token_Type_Symbol, 7, "builtin ", { 0 } }; AstNode builtin_package_node = { Ast_Kind_Symbol, Ast_Flag_No_Clone, &builtin_package_token, NULL }; @@ -44,6 +52,13 @@ const BuiltinSymbol builtin_symbols[] = { { NULL, "f64", (AstNode *) &basic_type_f64 }, { NULL, "rawptr", (AstNode *) &basic_type_rawptr }, + { "simd", "i8x16", (AstNode *) &basic_type_i8x16 }, + { "simd", "i16x8", (AstNode *) &basic_type_i16x8 }, + { "simd", "i32x4", (AstNode *) &basic_type_i32x4 }, + { "simd", "i64x2", (AstNode *) &basic_type_i64x2 }, + { "simd", "f32x4", (AstNode *) &basic_type_f32x4 }, + { "simd", "f64x2", (AstNode *) &basic_type_f64x2 }, + { "builtin", "__heap_start", (AstNode *) &builtin_heap_start }, { "builtin", "__stack_top", (AstNode *) &builtin_stack_top }, diff --git a/src/onyxtypes.c b/src/onyxtypes.c index 0b4e0be6..691a5924 100644 --- a/src/onyxtypes.c +++ b/src/onyxtypes.c @@ -5,23 +5,30 @@ // NOTE: These have to be in the same order as Basic Type basic_types[] = { - { Type_Kind_Basic, 0, { Basic_Kind_Void, 0, 0, 1, "void" } }, - - { Type_Kind_Basic, 0, { Basic_Kind_Bool, Basic_Flag_Boolean, 1, 1, "bool" } }, - - { Type_Kind_Basic, 0, { Basic_Kind_I8, Basic_Flag_Integer, 1, 1, "i8" } }, - { Type_Kind_Basic, 0, { Basic_Kind_U8, Basic_Flag_Integer | Basic_Flag_Unsigned, 1, 1, "u8" } }, - { Type_Kind_Basic, 0, { Basic_Kind_I16, Basic_Flag_Integer, 2, 2, "i16" } }, - { Type_Kind_Basic, 0, { Basic_Kind_U16, Basic_Flag_Integer | Basic_Flag_Unsigned, 2, 2, "u16" } }, - { Type_Kind_Basic, 0, { Basic_Kind_I32, Basic_Flag_Integer, 4, 4, "i32" } }, - { Type_Kind_Basic, 0, { Basic_Kind_U32, Basic_Flag_Integer | Basic_Flag_Unsigned, 4, 4, "u32" } }, - { Type_Kind_Basic, 0, { Basic_Kind_I64, Basic_Flag_Integer, 8, 8, "i64" } }, - { Type_Kind_Basic, 0, { Basic_Kind_U64, Basic_Flag_Integer | Basic_Flag_Unsigned, 8, 8, "u64" } }, - - { Type_Kind_Basic, 0, { Basic_Kind_F32, Basic_Flag_Float, 4, 4, "f32" } }, - { Type_Kind_Basic, 0, { Basic_Kind_F64, Basic_Flag_Float, 8, 4, "f64" } }, - - { Type_Kind_Basic, 0, { Basic_Kind_Rawptr, Basic_Flag_Pointer, 4, 4, "rawptr" } }, + { Type_Kind_Basic, 0, { Basic_Kind_Void, 0, 0, 1, "void" } }, + + { Type_Kind_Basic, 0, { Basic_Kind_Bool, Basic_Flag_Boolean, 1, 1, "bool" } }, + + { Type_Kind_Basic, 0, { Basic_Kind_I8, Basic_Flag_Integer, 1, 1, "i8" } }, + { Type_Kind_Basic, 0, { Basic_Kind_U8, Basic_Flag_Integer | Basic_Flag_Unsigned, 1, 1, "u8" } }, + { Type_Kind_Basic, 0, { Basic_Kind_I16, Basic_Flag_Integer, 2, 2, "i16" } }, + { Type_Kind_Basic, 0, { Basic_Kind_U16, Basic_Flag_Integer | Basic_Flag_Unsigned, 2, 2, "u16" } }, + { Type_Kind_Basic, 0, { Basic_Kind_I32, Basic_Flag_Integer, 4, 4, "i32" } }, + { Type_Kind_Basic, 0, { Basic_Kind_U32, Basic_Flag_Integer | Basic_Flag_Unsigned, 4, 4, "u32" } }, + { Type_Kind_Basic, 0, { Basic_Kind_I64, Basic_Flag_Integer, 8, 8, "i64" } }, + { Type_Kind_Basic, 0, { Basic_Kind_U64, Basic_Flag_Integer | Basic_Flag_Unsigned, 8, 8, "u64" } }, + + { Type_Kind_Basic, 0, { Basic_Kind_F32, Basic_Flag_Float, 4, 4, "f32" } }, + { Type_Kind_Basic, 0, { Basic_Kind_F64, Basic_Flag_Float, 8, 4, "f64" } }, + + { Type_Kind_Basic, 0, { Basic_Kind_Rawptr, Basic_Flag_Pointer, 4, 4, "rawptr" } }, + + { Type_Kind_Basic, 0, { Basic_Kind_I8X16, Basic_Flag_SIMD, 16, 16, "i8x16" } }, + { Type_Kind_Basic, 0, { Basic_Kind_I16X8, Basic_Flag_SIMD, 16, 16, "i16x8" } }, + { Type_Kind_Basic, 0, { Basic_Kind_I32X4, Basic_Flag_SIMD, 16, 16, "i32x4" } }, + { Type_Kind_Basic, 0, { Basic_Kind_I64X2, Basic_Flag_SIMD, 16, 16, "i64x2" } }, + { Type_Kind_Basic, 0, { Basic_Kind_F32X4, Basic_Flag_SIMD, 16, 16, "f32x4" } }, + { Type_Kind_Basic, 0, { Basic_Kind_F64X2, Basic_Flag_SIMD, 16, 16, "f64x2" } }, }; b32 types_are_surface_compatible(Type* t1, Type* t2) { diff --git a/src/onyxwasm.c b/src/onyxwasm.c index d98c8a47..6c57c0c6 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -9,6 +9,7 @@ #define WASM_TYPE_INT64 0x7E #define WASM_TYPE_FLOAT32 0x7D #define WASM_TYPE_FLOAT64 0x7C +#define WASM_TYPE_VAR128 0x7B #define WASM_TYPE_VOID 0x00 #else #define WASM_TYPE_INT32 'A' @@ -237,6 +238,7 @@ static WasmType onyx_type_to_wasm_type(Type* type) { if (basic->size <= 4) return WASM_TYPE_FLOAT32; if (basic->size == 8) return WASM_TYPE_FLOAT64; } + if (basic->flags & Basic_Flag_SIMD) return WASM_TYPE_VAR128; if (basic->size == 0) return WASM_TYPE_VOID; } @@ -246,10 +248,11 @@ static WasmType onyx_type_to_wasm_type(Type* type) { static i32 generate_type_idx(OnyxWasmModule* mod, Type* ft); static i32 get_element_idx(OnyxWasmModule* mod, AstFunction* func); -#define LOCAL_I32 0x000000000 -#define LOCAL_I64 0x100000000 -#define LOCAL_F32 0x300000000 -#define LOCAL_F64 0x700000000 +#define LOCAL_I32 0x000000000 +#define LOCAL_I64 0x100000000 +#define LOCAL_F32 0x300000000 +#define LOCAL_F64 0x700000000 +#define LOCAL_V128 0xf00000000 static b32 local_is_wasm_local(AstLocal* local) { if (local->flags & Ast_Flag_Address_Taken) return 0; @@ -265,12 +268,14 @@ static u64 local_raw_allocate(LocalAllocator* la, WasmType wt) { if (wt == WASM_TYPE_INT64) idx = 1; if (wt == WASM_TYPE_FLOAT32) idx = 2; if (wt == WASM_TYPE_FLOAT64) idx = 3; + if (wt == WASM_TYPE_VAR128) idx = 4; u64 flag_bits = LOCAL_IS_WASM; if (wt == WASM_TYPE_INT32) flag_bits |= LOCAL_I32; if (wt == WASM_TYPE_INT64) flag_bits |= LOCAL_I64; if (wt == WASM_TYPE_FLOAT32) flag_bits |= LOCAL_F32; if (wt == WASM_TYPE_FLOAT64) flag_bits |= LOCAL_F64; + if (wt == WASM_TYPE_VAR128) flag_bits |= LOCAL_V128; if (la->freed[idx] > 0) { la->freed[idx]--; @@ -289,6 +294,7 @@ static void local_raw_free(LocalAllocator* la, WasmType wt) { if (wt == WASM_TYPE_INT64) idx = 1; if (wt == WASM_TYPE_FLOAT32) idx = 2; if (wt == WASM_TYPE_FLOAT64) idx = 3; + if (wt == WASM_TYPE_VAR128) idx = 4; assert(la->allocated[idx] > 0 && la->freed[idx] < la->allocated[idx]); @@ -346,6 +352,7 @@ static u64 local_lookup_idx(LocalAllocator* la, u64 value) { if (value & 0x100000000) idx += la->allocated[0]; if (value & 0x200000000) idx += la->allocated[1]; if (value & 0x400000000) idx += la->allocated[2]; + if (value & 0x800000000) idx += la->allocated[3]; return (u64) idx; } @@ -3030,7 +3037,8 @@ static i32 output_locals(WasmFunc* func, bh_buffer* buff) { (i32) (func->locals.allocated[0] != 0) + (i32) (func->locals.allocated[1] != 0) + (i32) (func->locals.allocated[2] != 0) + - (i32) (func->locals.allocated[3] != 0); + (i32) (func->locals.allocated[3] != 0) + + (i32) (func->locals.allocated[4] != 0); i32 leb_len; u8* leb = uint_to_uleb128((u64) total_locals, &leb_len); @@ -3056,6 +3064,11 @@ static i32 output_locals(WasmFunc* func, bh_buffer* buff) { bh_buffer_append(buff, leb, leb_len); bh_buffer_write_byte(buff, WASM_TYPE_FLOAT64); } + if (func->locals.allocated[4] != 0) { + leb = uint_to_uleb128((u64) func->locals.allocated[4], &leb_len); + bh_buffer_append(buff, leb, leb_len); + bh_buffer_write_byte(buff, WASM_TYPE_VAR128); + } return buff->length - prev_len; }