added 'simd' package with simd types
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 9 Sep 2020 13:30:25 +0000 (08:30 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 9 Sep 2020 13:30:25 +0000 (08:30 -0500)
.vimspector.json
Makefile
include/onyxtypes.h
include/onyxwasm.h
misc/onyx.sublime-syntax
misc/onyx.vim
onyx
progs/simd_test.onyx [new file with mode: 0644]
src/onyxbuiltins.c
src/onyxtypes.c
src/onyxwasm.c

index bf221152ebc25a86b65cb47f8b5eb9d759a91372..5cd4edea86e32015233103e6784fbc00556d0f7e 100644 (file)
@@ -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": [],
index 8754d4eeb0779f3a48958b4cd49c601db6938f80..4778e4beac75d78cb2eb4ae56afce244e4aa3789 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-RELEASE=1
+RELEASE=0
 
 OBJ_FILES=\
        build/onyxlex.o \
index 5dfe489a3d8ee77c8ba92f00cab43c354987d6fe..7f9852371aab4779bd75c048019539333a9c2a39 100644 (file)
@@ -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,
index 4c3e6ea71aa92e5b58e38437445b30651381f22f..2328a04da109fd2db2c9fd07efcab797cee87773 100644 (file)
@@ -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;
index 6d0bbfcd6a45c12f53638ec3173e7645ecdd40db..5bbabea66ca58c03a72652c3bacc1e493fb7c988 100644 (file)
@@ -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
index e037825fb8743d14f8d26ac0a73552785ce67aeb..99bea6e5813f32d4505524991f11f73fc9e312da 100644 (file)
@@ -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 a68a99c184e98d83735ad196e968018426c8bd1c..0a728275f0036df5086b0f2a7d399089058ae162 100755 (executable)
Binary files a/onyx and b/onyx differ
diff --git a/progs/simd_test.onyx b/progs/simd_test.onyx
new file mode 100644 (file)
index 0000000..cf59c92
--- /dev/null
@@ -0,0 +1,10 @@
+package main
+
+#include_file "core/std/wasi"
+
+use package core
+use package simd
+
+main :: proc (args: [] cstring) {
+    x : i32x4;
+}
index 6362331e1a7e738455004be3d8052c91511fee82..fa1bb321526fbba6874129cb4c298c52fb116f22 100644 (file)
@@ -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 },
 
index 0b4e0be63c96eef610b4afc0c69258652280780f..691a59248d6c98e0283ce96c209be05d51b12520 100644 (file)
@@ -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) {
index d98c8a47f90a7694f8c4f6d3b830223c77c441a7..6c57c0c653f46834662b1afec4df1d6459153968 100644 (file)
@@ -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;
 }