Added all other intrinsics (for now)
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 9 Jul 2020 14:49:05 +0000 (09:49 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 9 Jul 2020 14:49:05 +0000 (09:49 -0500)
include/onyxastnodes.h
onyx
progs/test.onyx
src/onyxchecker.c
src/onyxwasm.c

index 8b7a4d098f170ad9af851e02f630ad06dec5c06b..ecc36099424663882d6279d4413faecfd43d9c03 100644 (file)
@@ -250,8 +250,52 @@ struct AstNodeArgument {
 typedef enum OnyxIntrinsic {
     ONYX_INTRINSIC_UNDEFINED,
 
-    ONYX_INTRINSIC_FLOAT32_SQRT,
-    ONYX_INTRINSIC_FLOAT64_SQRT,
+    ONYX_INTRINSIC_MEMORY_SIZE,
+    ONYX_INTRINSIC_MEMORY_GROW,
+
+    ONYX_INTRINSIC_I32_CLZ,
+    ONYX_INTRINSIC_I32_CTZ,
+    ONYX_INTRINSIC_I32_POPCNT,
+    ONYX_INTRINSIC_I32_AND,
+    ONYX_INTRINSIC_I32_OR,
+    ONYX_INTRINSIC_I32_XOR,
+    ONYX_INTRINSIC_I32_SHL,
+    ONYX_INTRINSIC_I32_SLR,
+    ONYX_INTRINSIC_I32_SAR,
+    ONYX_INTRINSIC_I32_ROTL,
+    ONYX_INTRINSIC_I32_ROTR,
+
+    ONYX_INTRINSIC_I64_CLZ,
+    ONYX_INTRINSIC_I64_CTZ,
+    ONYX_INTRINSIC_I64_POPCNT,
+    ONYX_INTRINSIC_I64_AND,
+    ONYX_INTRINSIC_I64_OR,
+    ONYX_INTRINSIC_I64_XOR,
+    ONYX_INTRINSIC_I64_SHL,
+    ONYX_INTRINSIC_I64_SLR,
+    ONYX_INTRINSIC_I64_SAR,
+    ONYX_INTRINSIC_I64_ROTL,
+    ONYX_INTRINSIC_I64_ROTR,
+
+    ONYX_INTRINSIC_F32_ABS,
+    ONYX_INTRINSIC_F32_CEIL,
+    ONYX_INTRINSIC_F32_FLOOR,
+    ONYX_INTRINSIC_F32_TRUNC,
+    ONYX_INTRINSIC_F32_NEAREST,
+    ONYX_INTRINSIC_F32_SQRT,
+    ONYX_INTRINSIC_F32_MIN,
+    ONYX_INTRINSIC_F32_MAX,
+    ONYX_INTRINSIC_F32_COPYSIGN,
+
+    ONYX_INTRINSIC_F64_ABS,
+    ONYX_INTRINSIC_F64_CEIL,
+    ONYX_INTRINSIC_F64_FLOOR,
+    ONYX_INTRINSIC_F64_TRUNC,
+    ONYX_INTRINSIC_F64_NEAREST,
+    ONYX_INTRINSIC_F64_SQRT,
+    ONYX_INTRINSIC_F64_MIN,
+    ONYX_INTRINSIC_F64_MAX,
+    ONYX_INTRINSIC_F64_COPYSIGN,
 } OnyxIntrinsic;
 
 // NOTE: This needs to have 'arguments' in the
diff --git a/onyx b/onyx
index 0d7801ec9f78940218113e72d96d622d38e674d9..11e0a223d083689be923236ac124cff10a443b56 100755 (executable)
Binary files a/onyx and b/onyx differ
index 47fa474015d122f8ea7ae5ee462f3cb2b7dd5cee..f70b68168dc2fe079721eac505e8b4495a6f2417 100644 (file)
@@ -11,9 +11,53 @@ export in_unit_circle :: proc (x: f32, y: f32) -> bool {
     return (x * x) + (y * y) < 1.0f;
 }
 
-sqrt_f32 ::
-    proc #intrinsic
-    (val: f32) -> f32 ---
+memory_size  :: proc #intrinsic -> i32 ---
+memory_grow  :: proc #intrinsic -> i32 ---
+
+clz_i32      :: proc #intrinsic (val: i32) -> i32 ---
+ctz_i32      :: proc #intrinsic (val: i32) -> i32 ---
+popcnt_i32   :: proc #intrinsic (val: i32) -> i32 ---
+and_i32      :: proc #intrinsic (val: i32) -> i32 ---
+or_i32       :: proc #intrinsic (val: i32) -> i32 ---
+xor_i32      :: proc #intrinsic (val: i32) -> i32 ---
+shl_i32      :: proc #intrinsic (val: i32) -> i32 ---
+slr_i32      :: proc #intrinsic (val: i32) -> i32 ---
+sar_i32      :: proc #intrinsic (val: i32) -> i32 ---
+rotl_i32     :: proc #intrinsic (val: i32) -> i32 ---
+rotr_i32     :: proc #intrinsic (val: i32) -> i32 ---
+
+clz_i64      :: proc #intrinsic (val: i64) -> i64 ---
+ctz_i64      :: proc #intrinsic (val: i64) -> i64 ---
+popcnt_i64   :: proc #intrinsic (val: i64) -> i64 ---
+and_i64      :: proc #intrinsic (val: i64) -> i64 ---
+or_i64       :: proc #intrinsic (val: i64) -> i64 ---
+xor_i64      :: proc #intrinsic (val: i64) -> i64 ---
+shl_i64      :: proc #intrinsic (val: i64) -> i64 ---
+slr_i64      :: proc #intrinsic (val: i64) -> i64 ---
+sar_i64      :: proc #intrinsic (val: i64) -> i64 ---
+rotl_i64     :: proc #intrinsic (val: i64) -> i64 ---
+rotr_i64     :: proc #intrinsic (val: i64) -> i64 ---
+
+abs_f32      :: proc #intrinsic (val: f32) -> f32 ---
+ceil_f32     :: proc #intrinsic (val: f32) -> f32 ---
+floor_f32    :: proc #intrinsic (val: f32) -> f32 ---
+trunc_f32    :: proc #intrinsic (val: f32) -> f32 ---
+nearest_f32  :: proc #intrinsic (val: f32) -> f32 ---
+sqrt_f32     :: proc #intrinsic (val: f32) -> f32 ---
+min_f32      :: proc #intrinsic (val: f32) -> f32 ---
+max_f32      :: proc #intrinsic (val: f32) -> f32 ---
+copysign_f32 :: proc #intrinsic (val: f32) -> f32 ---
+
+abs_f64      :: proc #intrinsic (val: f64) -> f64 ---
+ceil_f64     :: proc #intrinsic (val: f64) -> f64 ---
+floor_f64    :: proc #intrinsic (val: f64) -> f64 ---
+trunc_f64    :: proc #intrinsic (val: f64) -> f64 ---
+nearest_f64  :: proc #intrinsic (val: f64) -> f64 ---
+sqrt_f64     :: proc #intrinsic (val: f64) -> f64 ---
+min_f64      :: proc #intrinsic (val: f64) -> f64 ---
+max_f64      :: proc #intrinsic (val: f64) -> f64 ---
+copysign_f64 :: proc #intrinsic (val: f64) -> f64 ---
+
 
 // This is the entry point
 export main2 :: proc {
@@ -66,6 +110,7 @@ export main2 :: proc {
 
 export main :: proc {
     print_f32(sqrt_f32(2.0f));
+
     print_i32(5 * 6 + 2 * 3);
     print_bool(in_unit_circle(0.5f, 0.5f));
 
index 27e4a4c4d3248e22c3572dc291133ca145cc8975..dfc905cc94731821f15bcd9104a8d769f942a39c 100644 (file)
@@ -126,13 +126,58 @@ static void check_call(OnyxSemPassState* state, AstNodeCall* call) {
         call->callee = NULL;
 
         onyx_token_null_toggle(callee->base.token);
+
         char* intr_name = callee->base.token->token;
-        if (!strcmp("sqrt_f32", intr_name)) {
-            ((AstNodeIntrinsicCall *) call)->intrinsic = ONYX_INTRINSIC_FLOAT32_SQRT;
-        }
-        else if (!strcmp("sqrt_f64", intr_name)) {
-            ((AstNodeIntrinsicCall *) call)->intrinsic = ONYX_INTRINSIC_FLOAT64_SQRT;
-        }
+        OnyxIntrinsic intrinsic = ONYX_INTRINSIC_UNDEFINED;
+
+        if (!strcmp("memory_size", intr_name))       intrinsic = ONYX_INTRINSIC_MEMORY_SIZE;
+        else if (!strcmp("memory_grow", intr_name))  intrinsic = ONYX_INTRINSIC_MEMORY_GROW;
+
+        else if (!strcmp("clz_i32", intr_name))      intrinsic = ONYX_INTRINSIC_I32_CLZ;
+        else if (!strcmp("ctz_i32", intr_name))      intrinsic = ONYX_INTRINSIC_I32_CTZ;
+        else if (!strcmp("popcnt_i32", intr_name))   intrinsic = ONYX_INTRINSIC_I32_POPCNT;
+        else if (!strcmp("and_i32", intr_name))      intrinsic = ONYX_INTRINSIC_I32_AND;
+        else if (!strcmp("or_i32", intr_name))       intrinsic = ONYX_INTRINSIC_I32_OR;
+        else if (!strcmp("xor_i32", intr_name))      intrinsic = ONYX_INTRINSIC_I32_XOR;
+        else if (!strcmp("shl_i32", intr_name))      intrinsic = ONYX_INTRINSIC_I32_SHL;
+        else if (!strcmp("slr_i32", intr_name))      intrinsic = ONYX_INTRINSIC_I32_SLR;
+        else if (!strcmp("sar_i32", intr_name))      intrinsic = ONYX_INTRINSIC_I32_SAR;
+        else if (!strcmp("rotl_i32", intr_name))     intrinsic = ONYX_INTRINSIC_I32_ROTL;
+        else if (!strcmp("rotr_i32", intr_name))     intrinsic = ONYX_INTRINSIC_I32_ROTR;
+
+        else if (!strcmp("clz_i64", intr_name))      intrinsic = ONYX_INTRINSIC_I64_CLZ;
+        else if (!strcmp("ctz_i64", intr_name))      intrinsic = ONYX_INTRINSIC_I64_CTZ;
+        else if (!strcmp("popcnt_i64", intr_name))   intrinsic = ONYX_INTRINSIC_I64_POPCNT;
+        else if (!strcmp("and_i64", intr_name))      intrinsic = ONYX_INTRINSIC_I64_AND;
+        else if (!strcmp("or_i64", intr_name))       intrinsic = ONYX_INTRINSIC_I64_OR;
+        else if (!strcmp("xor_i64", intr_name))      intrinsic = ONYX_INTRINSIC_I64_XOR;
+        else if (!strcmp("shl_i64", intr_name))      intrinsic = ONYX_INTRINSIC_I64_SHL;
+        else if (!strcmp("slr_i64", intr_name))      intrinsic = ONYX_INTRINSIC_I64_SLR;
+        else if (!strcmp("sar_i64", intr_name))      intrinsic = ONYX_INTRINSIC_I64_SAR;
+        else if (!strcmp("rotl_i64", intr_name))     intrinsic = ONYX_INTRINSIC_I64_ROTL;
+        else if (!strcmp("rotr_i64", intr_name))     intrinsic = ONYX_INTRINSIC_I64_ROTR;
+
+        else if (!strcmp("abs_f32", intr_name))      intrinsic = ONYX_INTRINSIC_F32_ABS;
+        else if (!strcmp("ceil_f32", intr_name))     intrinsic = ONYX_INTRINSIC_F32_CEIL;
+        else if (!strcmp("floor_f32", intr_name))    intrinsic = ONYX_INTRINSIC_F32_FLOOR;
+        else if (!strcmp("trunc_f32", intr_name))    intrinsic = ONYX_INTRINSIC_F32_TRUNC;
+        else if (!strcmp("nearest_f32", intr_name))  intrinsic = ONYX_INTRINSIC_F32_NEAREST;
+        else if (!strcmp("sqrt_f32", intr_name))     intrinsic = ONYX_INTRINSIC_F32_SQRT;
+        else if (!strcmp("min_f32", intr_name))      intrinsic = ONYX_INTRINSIC_F32_MIN;
+        else if (!strcmp("max_f32", intr_name))      intrinsic = ONYX_INTRINSIC_F32_MAX;
+        else if (!strcmp("copysign_f32", intr_name)) intrinsic = ONYX_INTRINSIC_F32_COPYSIGN;
+
+        else if (!strcmp("abs_f64", intr_name))      intrinsic = ONYX_INTRINSIC_F64_ABS;
+        else if (!strcmp("ceil_f64", intr_name))     intrinsic = ONYX_INTRINSIC_F64_CEIL;
+        else if (!strcmp("floor_f64", intr_name))    intrinsic = ONYX_INTRINSIC_F64_FLOOR;
+        else if (!strcmp("trunc_f64", intr_name))    intrinsic = ONYX_INTRINSIC_F64_TRUNC;
+        else if (!strcmp("nearest_f64", intr_name))  intrinsic = ONYX_INTRINSIC_F64_NEAREST;
+        else if (!strcmp("sqrt_f64", intr_name))     intrinsic = ONYX_INTRINSIC_F64_SQRT;
+        else if (!strcmp("min_f64", intr_name))      intrinsic = ONYX_INTRINSIC_F64_MIN;
+        else if (!strcmp("max_f64", intr_name))      intrinsic = ONYX_INTRINSIC_F64_MAX;
+        else if (!strcmp("copysign_f64", intr_name)) intrinsic = ONYX_INTRINSIC_F64_COPYSIGN;
+
+        ((AstNodeIntrinsicCall *)call)->intrinsic = intrinsic;
 
         onyx_token_null_toggle(callee->base.token);
     }
index 6001f20f11c98a828bb9bb53f99ed340b2dba06f..20faa77a24263087de8750cf2a37112e82aa526c 100644 (file)
@@ -209,6 +209,9 @@ static WasmType onyx_type_to_wasm_type(TypeInfo* type) {
     return WASM_TYPE_VOID;
 }
 
+#define WI(instr) bh_arr_push(code, ((WasmInstruction){ instr, 0x00 }));
+#define WID(instr, data) bh_arr_push(code, ((WasmInstruction){ instr, data }));
+
 static void compile_function_body(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeFunction* fd);
 static void compile_block(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeBlock* block);
 static void compile_statement(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNode* stmt);
@@ -233,7 +236,7 @@ static void compile_function_body(OnyxWasmModule* mod, bh_arr(WasmInstruction)*
         compile_statement(mod, &code, stmt);
     }
 
-    bh_arr_push(code, ((WasmInstruction){ WI_BLOCK_END, 0x00 }));
+    WI(WI_BLOCK_END);
 
     *pcode = code;
 }
@@ -241,13 +244,13 @@ static void compile_function_body(OnyxWasmModule* mod, bh_arr(WasmInstruction)*
 static void compile_block(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeBlock* block) {
     bh_arr(WasmInstruction) code = *pcode;
 
-    bh_arr_push(code, ((WasmInstruction){ WI_BLOCK_START, 0x40 }));
+    WID(WI_BLOCK_START, 0x40);
 
     forll (AstNode, stmt, block->body, next) {
         compile_statement(mod, &code, stmt);
     }
 
-    bh_arr_push(code, ((WasmInstruction){ WI_BLOCK_END, 0x00 }));
+    WI(WI_BLOCK_END);
 
     *pcode = code;
 }
@@ -270,7 +273,7 @@ static void compile_structured_jump(OnyxWasmModule* mod, bh_arr(WasmInstruction)
     }
 
     if (success) {
-        bh_arr_push(code, ((WasmInstruction){ WI_JUMP, labelidx }));
+        WID(WI_JUMP, labelidx);
     } else {
         assert(("Invalid structured jump", 0));
     }
@@ -308,12 +311,12 @@ static void compile_assign_lval(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pc
     if (lval->kind == AST_NODE_KIND_LOCAL || lval->kind == AST_NODE_KIND_PARAM) {
         i32 localidx = (i32) bh_imap_get(&mod->local_map, (u64) lval);
 
-        bh_arr_push(code, ((WasmInstruction){ WI_LOCAL_SET, localidx }));
+        WID(WI_LOCAL_SET, localidx);
 
     } else if (lval->kind == AST_NODE_KIND_GLOBAL) {
         i32 globalidx = (i32) bh_imap_get(&mod->global_map, (u64) lval);
 
-        bh_arr_push(code, ((WasmInstruction){ WI_GLOBAL_SET, globalidx }));
+        WID(WI_GLOBAL_SET, globalidx);
 
     } else {
         assert(("Invalid lval", 0));
@@ -326,7 +329,7 @@ static void compile_if(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstN
     bh_arr(WasmInstruction) code = *pcode;
 
     compile_expression(mod, &code, if_node->cond);
-    bh_arr_push(code, ((WasmInstruction){ WI_IF_START, 0x40 }));
+    WID(WI_IF_START, 0x40);
 
     bh_arr_push(mod->structured_jump_target, 0);
 
@@ -345,7 +348,7 @@ static void compile_if(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstN
     }
 
     if (if_node->false_block.as_if) {
-        bh_arr_push(code, ((WasmInstruction){ WI_ELSE, 0x00 }));
+        WI(WI_ELSE);
 
         if (if_node->false_block.as_if->base.kind == AST_NODE_KIND_IF) {
             forll (AstNode, stmt, (AstNode *) if_node->false_block.as_if, next) {
@@ -360,7 +363,7 @@ static void compile_if(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstN
 
     bh_arr_pop(mod->structured_jump_target);
 
-    bh_arr_push(code, ((WasmInstruction){ WI_IF_END, 0x00 }));
+    WI(WI_IF_END);
 
     *pcode = code;
 }
@@ -368,12 +371,12 @@ static void compile_if(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstN
 static void compile_while(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeWhile* while_node) {
     bh_arr(WasmInstruction) code = *pcode;
 
-    bh_arr_push(code, ((WasmInstruction){ WI_BLOCK_START, 0x40 }));
-    bh_arr_push(code, ((WasmInstruction){ WI_LOOP_START, 0x40 }));
+    WID(WI_BLOCK_START, 0x40);
+    WID(WI_LOOP_START, 0x40);
 
     compile_expression(mod, &code, while_node->cond);
-    bh_arr_push(code, ((WasmInstruction){ WI_I32_EQZ, 0x00 }));
-    bh_arr_push(code, ((WasmInstruction){ WI_COND_JUMP, 0x01 }));
+    WI(WI_I32_EQZ);
+    WID(WI_COND_JUMP, 0x01);
 
     bh_arr_push(mod->structured_jump_target, 1);
     bh_arr_push(mod->structured_jump_target, 2);
@@ -385,10 +388,10 @@ static void compile_while(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, A
     bh_arr_pop(mod->structured_jump_target);
     bh_arr_pop(mod->structured_jump_target);
 
-    bh_arr_push(code, ((WasmInstruction){ WI_JUMP, 0x00 }));
+    WID(WI_JUMP, 0x00);
 
-    bh_arr_push(code, ((WasmInstruction){ WI_LOOP_END, 0x00 }));
-    bh_arr_push(code, ((WasmInstruction){ WI_BLOCK_END, 0x00 }));
+    WI(WI_LOOP_END);
+    WI(WI_BLOCK_END);
 
     *pcode = code;
 }
@@ -462,7 +465,7 @@ static void compile_binop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, A
     compile_expression(mod, &code, binop->left);
     compile_expression(mod, &code, binop->right);
 
-    bh_arr_push(code, ((WasmInstruction){ binop_instr, 0x00 }));
+    WI(binop_instr);
 
     *pcode = code;
 }
@@ -476,23 +479,23 @@ static void compile_unaryop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode,
                 TypeInfoKind type_kind = unop->base.type->kind;
 
                 if (type_kind == TYPE_INFO_KIND_INT32) {
-                    bh_arr_push(code, ((WasmInstruction){ WI_I32_CONST, 0x00 }));
+                    WID(WI_I32_CONST, 0x00);
                     compile_expression(mod, &code, unop->expr);
-                    bh_arr_push(code, ((WasmInstruction){ WI_I32_SUB, 0x00 }));
+                    WI(WI_I32_SUB);
 
                 } else if (type_kind == TYPE_INFO_KIND_INT64) {
-                    bh_arr_push(code, ((WasmInstruction){ WI_I64_CONST, 0x00 }));
+                    WID(WI_I64_CONST, 0x00);
                     compile_expression(mod, &code, unop->expr);
-                    bh_arr_push(code, ((WasmInstruction){ WI_I64_SUB, 0x00 }));
+                    WI(WI_I64_SUB);
 
                 } else {
                     compile_expression(mod, &code, unop->expr);
 
                     if (type_kind == TYPE_INFO_KIND_FLOAT32)
-                        bh_arr_push(code, ((WasmInstruction){ WI_F32_NEG, 0x00 }));
+                        WI(WI_F32_NEG);
 
                     if (type_kind == TYPE_INFO_KIND_FLOAT64)
-                        bh_arr_push(code, ((WasmInstruction){ WI_F32_NEG, 0x00 }));
+                        WI(WI_F64_NEG);
                 }
 
                 break;
@@ -501,7 +504,7 @@ static void compile_unaryop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode,
         case ONYX_UNARY_OP_NOT:
             compile_expression(mod, &code, unop->expr);
 
-            bh_arr_push(code, ((WasmInstruction){ WI_I32_EQZ, 0x00 }));
+            WI(WI_I32_EQZ);
             break;
 
         case ONYX_UNARY_OP_CAST: compile_cast(mod, &code, unop); break;
@@ -543,17 +546,54 @@ static void compile_intrinsic_call(OnyxWasmModule* mod, bh_arr(WasmInstruction)*
     }
 
     switch (call->intrinsic) {
-        case ONYX_INTRINSIC_UNDEFINED:
-            assert(0);
-            break;
-
-        case ONYX_INTRINSIC_FLOAT32_SQRT:
-            bh_arr_push(code, ((WasmInstruction){ WI_F32_SQRT, 0x00}));
-            break;
-
-        case ONYX_INTRINSIC_FLOAT64_SQRT:
-            bh_arr_push(code, ((WasmInstruction){ WI_F64_SQRT, 0x00 }));
-            break;
+        case ONYX_INTRINSIC_MEMORY_SIZE:  WID(WI_MEMORY_SIZE, 0x00); break;
+        case ONYX_INTRINSIC_MEMORY_GROW:  WID(WI_MEMORY_GROW, 0x00); break;
+
+        case ONYX_INTRINSIC_I32_CLZ:      WI(WI_I32_CLZ); break;
+        case ONYX_INTRINSIC_I32_CTZ:      WI(WI_I32_CTZ); break;
+        case ONYX_INTRINSIC_I32_POPCNT:   WI(WI_I32_POPCNT); break;
+        case ONYX_INTRINSIC_I32_AND:      WI(WI_I32_AND); break;
+        case ONYX_INTRINSIC_I32_OR:       WI(WI_I32_OR); break;
+        case ONYX_INTRINSIC_I32_XOR:      WI(WI_I32_XOR); break;
+        case ONYX_INTRINSIC_I32_SHL:      WI(WI_I32_SHL); break;
+        case ONYX_INTRINSIC_I32_SLR:      WI(WI_I32_SHR_U); break;
+        case ONYX_INTRINSIC_I32_SAR:      WI(WI_I32_SHR_S); break;
+        case ONYX_INTRINSIC_I32_ROTL:     WI(WI_I32_ROTL); break;
+        case ONYX_INTRINSIC_I32_ROTR:     WI(WI_I32_ROTR); break;
+
+        case ONYX_INTRINSIC_I64_CLZ:      WI(WI_I64_CLZ); break;
+        case ONYX_INTRINSIC_I64_CTZ:      WI(WI_I64_CTZ); break;
+        case ONYX_INTRINSIC_I64_POPCNT:   WI(WI_I64_POPCNT); break;
+        case ONYX_INTRINSIC_I64_AND:      WI(WI_I64_AND); break;
+        case ONYX_INTRINSIC_I64_OR:       WI(WI_I64_OR); break;
+        case ONYX_INTRINSIC_I64_XOR:      WI(WI_I64_XOR); break;
+        case ONYX_INTRINSIC_I64_SHL:      WI(WI_I64_SHL); break;
+        case ONYX_INTRINSIC_I64_SLR:      WI(WI_I64_SHR_U); break;
+        case ONYX_INTRINSIC_I64_SAR:      WI(WI_I64_SHR_S); break;
+        case ONYX_INTRINSIC_I64_ROTL:     WI(WI_I64_ROTL); break;
+        case ONYX_INTRINSIC_I64_ROTR:     WI(WI_I64_ROTR); break;
+
+        case ONYX_INTRINSIC_F32_ABS:      WI(WI_F32_ABS); break;
+        case ONYX_INTRINSIC_F32_CEIL:     WI(WI_F32_CEIL); break;
+        case ONYX_INTRINSIC_F32_FLOOR:    WI(WI_F32_FLOOR); break;
+        case ONYX_INTRINSIC_F32_TRUNC:    WI(WI_F32_TRUNC); break;
+        case ONYX_INTRINSIC_F32_NEAREST:  WI(WI_F32_NEAREST); break;
+        case ONYX_INTRINSIC_F32_SQRT:     WI(WI_F32_SQRT); break;
+        case ONYX_INTRINSIC_F32_MIN:      WI(WI_F32_MIN); break;
+        case ONYX_INTRINSIC_F32_MAX:      WI(WI_F32_MAX); break;
+        case ONYX_INTRINSIC_F32_COPYSIGN: WI(WI_F32_COPYSIGN); break;
+
+        case ONYX_INTRINSIC_F64_ABS:      WI(WI_F64_ABS); break;
+        case ONYX_INTRINSIC_F64_CEIL:     WI(WI_F64_CEIL); break;
+        case ONYX_INTRINSIC_F64_FLOOR:    WI(WI_F64_FLOOR); break;
+        case ONYX_INTRINSIC_F64_TRUNC:    WI(WI_F64_TRUNC); break;
+        case ONYX_INTRINSIC_F64_NEAREST:  WI(WI_F64_NEAREST); break;
+        case ONYX_INTRINSIC_F64_SQRT:     WI(WI_F64_SQRT); break;
+        case ONYX_INTRINSIC_F64_MIN:      WI(WI_F64_MIN); break;
+        case ONYX_INTRINSIC_F64_MAX:      WI(WI_F64_MAX); break;
+        case ONYX_INTRINSIC_F64_COPYSIGN: WI(WI_F64_COPYSIGN); break;
+
+        default: assert(("Unsupported intrinsic", 0));
     }
 
     *pcode = code;
@@ -576,7 +616,7 @@ static void compile_expression(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pco
             {
                 i32 localidx = (i32) bh_imap_get(&mod->local_map, (u64) expr);
 
-                bh_arr_push(code, ((WasmInstruction){ WI_LOCAL_GET, localidx }));
+                WID(WI_LOCAL_GET, localidx);
                 break;
             }
 
@@ -584,7 +624,7 @@ static void compile_expression(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pco
             {
                 i32 globalidx = (i32) bh_imap_get(&mod->global_map, (u64) expr);
 
-                bh_arr_push(code, ((WasmInstruction){ WI_GLOBAL_GET, globalidx }));
+                WID(WI_GLOBAL_GET, globalidx);
                 break;
             }
 
@@ -673,7 +713,7 @@ static void compile_cast(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, As
 
     WasmInstructionType cast_op = cast_map[fromidx][toidx];
     if (cast_op != WI_NOP) {
-        bh_arr_push(code, ((WasmInstruction){ cast_op, 0x00 }));
+        WI(cast_op);
     }
 
     *pcode = code;
@@ -686,7 +726,7 @@ static void compile_return(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode,
         compile_expression(mod, &code, ret->expr);
     }
 
-    bh_arr_push(code, ((WasmInstruction){ WI_RETURN, 0x00 }));
+    WI(WI_RETURN);
 
     *pcode = code;
 }
@@ -1256,6 +1296,8 @@ static void output_instruction(WasmInstruction* instr, bh_buffer* buff) {
         case WI_JUMP:
         case WI_COND_JUMP:
         case WI_IF_START:
+        case WI_MEMORY_SIZE:
+        case WI_MEMORY_GROW:
             leb = uint_to_uleb128((u64) instr->data.i1, &leb_len);
             bh_buffer_append(buff, leb, leb_len);
             break;