From bdc50827555399c51316273ef15b3358ca196e41 Mon Sep 17 00:00:00 2001 From: Volodymyr Shymanskyy Date: Fri, 1 May 2020 21:22:51 +0300 Subject: [PATCH] d_m3HasFloat - allow disabling float ops --- .github/workflows/tests.yml | 24 ++--- source/m3.h | 9 -- source/m3_compile.c | 209 ++++++++++++++++++++---------------- source/m3_compile.h | 7 ++ source/m3_config.h | 89 +++++++++++---- source/m3_core.c | 3 + source/m3_core.h | 5 + source/m3_env.c | 10 +- source/m3_env.h | 5 +- source/m3_exec.c | 5 +- source/m3_exec.h | 37 ++++--- source/m3_exec_defs.h | 12 +++ source/m3_info.c | 2 + source/m3_math_utils.h | 3 + 14 files changed, 261 insertions(+), 159 deletions(-) delete mode 100644 source/m3.h diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f7307b4..271bc77 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -435,18 +435,18 @@ jobs: run: | mkdir build cd build - g++ -xc++ -Dd_m3HasWASI -Dd_m3LogsDefined \ - -Dd_m3EnableOpTracing \ - -Dd_m3LogParse=1 \ - -Dd_m3LogModule=1 \ - -Dd_m3LogCompile=1 \ - -Dd_m3LogWasmStack=1 \ - -Dd_m3LogEmit=1 \ - -Dd_m3LogCodePages=1 \ - -Dd_m3LogExec=1 \ - -Dd_m3LogRuntime=1 \ - -Dd_m3LogStackTrace=1 \ - -Dd_m3LogNativeStack=1 \ + g++ -xc++ -Dd_m3HasWASI -DDEBUG \ + -Dd_m3EnableOpTracing=1 \ + -Dd_m3LogParse=1 \ + -Dd_m3LogModule=1 \ + -Dd_m3LogCompile=1 \ + -Dd_m3LogWasmStack=1 \ + -Dd_m3LogEmit=1 \ + -Dd_m3LogCodePages=1 \ + -Dd_m3LogExec=1 \ + -Dd_m3LogRuntime=1 \ + -Dd_m3LogStackTrace=1 \ + -Dd_m3LogNativeStack=1 \ -I../source ../source/*.c ../platforms/app/main.c \ -O3 -g0 -lm \ -o wasm3 diff --git a/source/m3.h b/source/m3.h deleted file mode 100644 index 219dc9a..0000000 --- a/source/m3.h +++ /dev/null @@ -1,9 +0,0 @@ - -#if defined(_MSC_VER) -#pragma message("m3.h is deprecated, please use wasm3.h") -#else -#warning "m3.h is deprecated, please use wasm3.h" -#endif - -#include "wasm3.h" - diff --git a/source/m3_compile.c b/source/m3_compile.c index 9a8dd4b..7b93788 100644 --- a/source/m3_compile.c +++ b/source/m3_compile.c @@ -24,7 +24,27 @@ #define none c_m3Type_none #define any (u8)-1 +#if d_m3HasFloat +static const IM3Operation c_preserveSetSlot [] = { NULL, op_PreserveSetSlot_i32, op_PreserveSetSlot_i64, op_PreserveSetSlot_f32, op_PreserveSetSlot_f64 }; static const IM3Operation c_setSetOps [] = { NULL, op_SetSlot_i32, op_SetSlot_i64, op_SetSlot_f32, op_SetSlot_f64 }; +static const IM3Operation c_setGlobalOps [] = { NULL, op_SetGlobal_i32, op_SetGlobal_i64, op_SetGlobal_f32, op_SetGlobal_f64 }; +static const IM3Operation c_setRegisterOps [] = { NULL, op_SetRegister_i32, op_SetRegister_i64, op_SetRegister_f32, op_SetRegister_f64 }; +#else +static const IM3Operation c_preserveSetSlot [] = { NULL, op_PreserveSetSlot_i32, op_PreserveSetSlot_i64, NULL, NULL }; +static const IM3Operation c_setSetOps [] = { NULL, op_SetSlot_i32, op_SetSlot_i64, NULL, NULL }; +static const IM3Operation c_setGlobalOps [] = { NULL, op_SetGlobal_i32, op_SetGlobal_i64, NULL, NULL }; +static const IM3Operation c_setRegisterOps [] = { NULL, op_SetRegister_i32, op_SetRegister_i64, NULL, NULL }; +#endif + +static const IM3Operation c_intSelectOps [2] [4] = { { op_Select_i32_rss, op_Select_i32_srs, op_Select_i32_ssr, op_Select_i32_sss }, + { op_Select_i64_rss, op_Select_i64_srs, op_Select_i64_ssr, op_Select_i64_sss } }; + +#if d_m3HasFloat +static const IM3Operation c_fpSelectOps [2] [2] [3] = { { { op_Select_f32_sss, op_Select_f32_srs, op_Select_f32_ssr }, // selector in slot + { op_Select_f32_rss, op_Select_f32_rrs, op_Select_f32_rsr } }, // selector in reg + { { op_Select_f64_sss, op_Select_f64_srs, op_Select_f64_ssr }, // selector in slot + { op_Select_f64_rss, op_Select_f64_rrs, op_Select_f64_rsr } } }; // selector in reg +#endif static const u16 c_m3RegisterUnallocated = 0; static const u16 c_slotUnused = 0xffff; @@ -403,6 +423,12 @@ M3Result Push (IM3Compilation o, u8 i_type, u16 i_location) { M3Result result = m3Err_none; +#if !d_m3HasFloat + if (i_type == c_m3Type_f32 || i_type == c_m3Type_f64) { + return m3Err_unknownOpcode; + } +#endif + u16 stackIndex = o->stackIndex++; // printf ("push: %d\n", (i32) i); if (stackIndex < d_m3MaxFunctionStackHeight) @@ -760,8 +786,6 @@ M3Result PreservedCopyTopSlot (IM3Compilation o, u16 i_destSlot, u16 i_preserv if (IsStackTopInRegister (o)) { - const IM3Operation c_preserveSetSlot [] = { NULL, op_PreserveSetSlot_i32, op_PreserveSetSlot_i64, op_PreserveSetSlot_f32, op_PreserveSetSlot_f64 }; - op = c_preserveSetSlot [type]; } else op = Is64BitType (type) ? op_PreserveCopySlot_64 : op_PreserveCopySlot_32; @@ -781,8 +805,6 @@ _ (EmitOp (o, op)); M3Result MoveStackTopToRegister (IM3Compilation o) { - static const IM3Operation setRegisterOps [] = { NULL, op_SetRegister_i32, op_SetRegister_i64, op_SetRegister_f32, op_SetRegister_f64 }; - M3Result result = m3Err_none; if (IsStackTopInSlot (o)) @@ -791,7 +813,7 @@ M3Result MoveStackTopToRegister (IM3Compilation o) _ (PreserveRegisterIfOccupied (o, type)); - IM3Operation op = setRegisterOps [type]; + IM3Operation op = c_setRegisterOps [type]; _ (EmitOp (o, op)); _ (EmitTopSlotAndPop (o)); @@ -907,6 +929,7 @@ _ (PushConst (o, value, c_m3Type_i64)); m3log (compile, } +#if d_m3HasFloat M3Result Compile_Const_f32 (IM3Compilation o, m3opcode_t i_opcode) { M3Result result; @@ -931,6 +954,7 @@ _ (PushConst (o, value.u, c_m3Type_f64)); _catch: return result; } +#endif #ifdef d_m3CompileExtendedOpcode @@ -1097,8 +1121,6 @@ M3Result Compile_SetGlobal (IM3Compilation o, M3Global * i_global) if (IsStackTopInRegister (o)) { - const IM3Operation c_setGlobalOps [] = { NULL, op_SetGlobal_i32, op_SetGlobal_i64, op_SetGlobal_f32, op_SetGlobal_f64 }; - op = c_setGlobalOps [type]; } else op = Is64BitType (type) ? op_SetGlobal_s64 : op_SetGlobal_s32; @@ -1611,13 +1633,6 @@ _ (CompileElseBlock (o, pc, blockType)); M3Result Compile_Select (IM3Compilation o, m3opcode_t i_opcode) { - static const IM3Operation intSelectOps [2] [4] = { { op_Select_i32_rss, op_Select_i32_srs, op_Select_i32_ssr, op_Select_i32_sss }, - { op_Select_i64_rss, op_Select_i64_srs, op_Select_i64_ssr, op_Select_i64_sss } }; - - static const IM3Operation fpSelectOps [2] [2] [3] = { { { op_Select_f32_sss, op_Select_f32_srs, op_Select_f32_ssr }, // selector in slot - { op_Select_f32_rss, op_Select_f32_rrs, op_Select_f32_rsr } }, // selector in reg - { { op_Select_f64_sss, op_Select_f64_srs, op_Select_f64_ssr }, // selector in slot - { op_Select_f64_rss, op_Select_f64_rrs, op_Select_f64_rsr } } }; // selector in reg M3Result result = m3Err_none; u16 slots [3] = { c_slotUnused, c_slotUnused, c_slotUnused }; @@ -1628,6 +1643,7 @@ M3Result Compile_Select (IM3Compilation o, m3opcode_t i_opcode) if (IsFpType (type)) { +#if d_m3HasFloat // not consuming a fp reg, so preserve if (not IsStackTopMinus1InRegister (o) and not IsStackTopMinus2InRegister (o)) @@ -1651,7 +1667,10 @@ _ (Pop (o)); _ (Pop (o)); } - op = fpSelectOps [type - c_m3Type_f32] [selectorInReg] [opIndex]; + op = c_fpSelectOps [type - c_m3Type_f32] [selectorInReg] [opIndex]; +#else + _throw (m3Err_unknownOpcode); +#endif } else if (IsIntType (type)) { @@ -1675,7 +1694,7 @@ _ (PreserveRegisterIfOccupied (o, type)); _ (Pop (o)); } - op = intSelectOps [type - c_m3Type_i32] [opIndex]; + op = c_intSelectOps [type - c_m3Type_i32] [opIndex]; } else if (not IsStackPolymorphic (o)) _throw (m3Err_functionStackUnderrun); @@ -1899,8 +1918,8 @@ const M3OpInfo c_operations [] = M3OP( "i32.load", 0, i_32, d_unaryOpList (i32, Load_i32), Compile_Load_Store ), // 0x28 M3OP( "i64.load", 0, i_64, d_unaryOpList (i64, Load_i64), Compile_Load_Store ), // 0x29 - M3OP( "f32.load", 0, f_32, d_unaryOpList (f32, Load_f32), Compile_Load_Store ), // 0x2a - M3OP( "f64.load", 0, f_64, d_unaryOpList (f64, Load_f64), Compile_Load_Store ), // 0x2b + M3OP_F( "f32.load", 0, f_32, d_unaryOpList (f32, Load_f32), Compile_Load_Store ), // 0x2a + M3OP_F( "f64.load", 0, f_64, d_unaryOpList (f64, Load_f64), Compile_Load_Store ), // 0x2b M3OP( "i32.load8_s", 0, i_32, d_unaryOpList (i32, Load_i8), Compile_Load_Store ), // 0x2c M3OP( "i32.load8_u", 0, i_32, d_unaryOpList (i32, Load_u8), Compile_Load_Store ), // 0x2d @@ -1916,8 +1935,8 @@ const M3OpInfo c_operations [] = M3OP( "i32.store", -2, none, d_binOpList (i32, Store_i32), Compile_Load_Store ), // 0x36 M3OP( "i64.store", -2, none, d_binOpList (i64, Store_i64), Compile_Load_Store ), // 0x37 - M3OP( "f32.store", -2, none, d_storeFpOpList (f32, Store_f32), Compile_Load_Store ), // 0x38 - M3OP( "f64.store", -2, none, d_storeFpOpList (f64, Store_f64), Compile_Load_Store ), // 0x39 + M3OP_F( "f32.store", -2, none, d_storeFpOpList (f32, Store_f32), Compile_Load_Store ), // 0x38 + M3OP_F( "f64.store", -2, none, d_storeFpOpList (f64, Store_f64), Compile_Load_Store ), // 0x39 M3OP( "i32.store8", -2, none, d_binOpList (i32, Store_u8), Compile_Load_Store ), // 0x3a M3OP( "i32.store16", -2, none, d_binOpList (i32, Store_i16), Compile_Load_Store ), // 0x3b @@ -1931,8 +1950,8 @@ const M3OpInfo c_operations [] = M3OP( "i32.const", 1, i_32, d_logOp (Const32), Compile_Const_i32 ), // 0x41 M3OP( "i64.const", 1, i_64, d_logOp (Const64), Compile_Const_i64 ), // 0x42 - M3OP( "f32.const", 1, f_32, d_emptyOpList, Compile_Const_f32 ), // 0x43 - M3OP( "f64.const", 1, f_64, d_emptyOpList, Compile_Const_f64 ), // 0x44 + M3OP_F( "f32.const", 1, f_32, d_emptyOpList, Compile_Const_f32 ), // 0x43 + M3OP_F( "f64.const", 1, f_64, d_emptyOpList, Compile_Const_f64 ), // 0x44 M3OP( "i32.eqz", 0, i_32, d_unaryOpList (i32, EqualToZero) ), // 0x45 M3OP( "i32.eq", -1, i_32, d_commutativeBinOpList (i32, Equal) ), // 0x46 @@ -1958,19 +1977,19 @@ const M3OpInfo c_operations [] = M3OP( "i64.ge_s", -1, i_32, d_binOpList (i64, GreaterThanOrEqual) ), // 0x59 M3OP( "i64.ge_u", -1, i_32, d_binOpList (u64, GreaterThanOrEqual) ), // 0x5a - M3OP( "f32.eq", -1, i_32, d_commutativeBinOpList (f32, Equal) ), // 0x5b - M3OP( "f32.ne", -1, i_32, d_commutativeBinOpList (f32, NotEqual) ), // 0x5c - M3OP( "f32.lt", -1, i_32, d_binOpList (f32, LessThan) ), // 0x5d - M3OP( "f32.gt", -1, i_32, d_binOpList (f32, GreaterThan) ), // 0x5e - M3OP( "f32.le", -1, i_32, d_binOpList (f32, LessThanOrEqual) ), // 0x5f - M3OP( "f32.ge", -1, i_32, d_binOpList (f32, GreaterThanOrEqual) ), // 0x60 + M3OP_F( "f32.eq", -1, i_32, d_commutativeBinOpList (f32, Equal) ), // 0x5b + M3OP_F( "f32.ne", -1, i_32, d_commutativeBinOpList (f32, NotEqual) ), // 0x5c + M3OP_F( "f32.lt", -1, i_32, d_binOpList (f32, LessThan) ), // 0x5d + M3OP_F( "f32.gt", -1, i_32, d_binOpList (f32, GreaterThan) ), // 0x5e + M3OP_F( "f32.le", -1, i_32, d_binOpList (f32, LessThanOrEqual) ), // 0x5f + M3OP_F( "f32.ge", -1, i_32, d_binOpList (f32, GreaterThanOrEqual) ), // 0x60 - M3OP( "f64.eq", -1, i_32, d_commutativeBinOpList (f64, Equal) ), // 0x61 - M3OP( "f64.ne", -1, i_32, d_commutativeBinOpList (f64, NotEqual) ), // 0x62 - M3OP( "f64.lt", -1, i_32, d_binOpList (f64, LessThan) ), // 0x63 - M3OP( "f64.gt", -1, i_32, d_binOpList (f64, GreaterThan) ), // 0x64 - M3OP( "f64.le", -1, i_32, d_binOpList (f64, LessThanOrEqual) ), // 0x65 - M3OP( "f64.ge", -1, i_32, d_binOpList (f64, GreaterThanOrEqual) ), // 0x66 + M3OP_F( "f64.eq", -1, i_32, d_commutativeBinOpList (f64, Equal) ), // 0x61 + M3OP_F( "f64.ne", -1, i_32, d_commutativeBinOpList (f64, NotEqual) ), // 0x62 + M3OP_F( "f64.lt", -1, i_32, d_binOpList (f64, LessThan) ), // 0x63 + M3OP_F( "f64.gt", -1, i_32, d_binOpList (f64, GreaterThan) ), // 0x64 + M3OP_F( "f64.le", -1, i_32, d_binOpList (f64, LessThanOrEqual) ), // 0x65 + M3OP_F( "f64.ge", -1, i_32, d_binOpList (f64, GreaterThanOrEqual) ), // 0x66 M3OP( "i32.clz", 0, i_32, d_unaryOpList (u32, Clz) ), // 0x67 M3OP( "i32.ctz", 0, i_32, d_unaryOpList (u32, Ctz) ), // 0x68 @@ -2012,70 +2031,70 @@ const M3OpInfo c_operations [] = M3OP( "i64.rotl", -1, i_64, d_binOpList (u64, Rotl) ), // 0x89 M3OP( "i64.rotr", -1, i_64, d_binOpList (u64, Rotr) ), // 0x8a - M3OP( "f32.abs", 0, f_32, d_unaryOpList(f32, Abs) ), // 0x8b - M3OP( "f32.neg", 0, f_32, d_unaryOpList(f32, Negate) ), // 0x8c - M3OP( "f32.ceil", 0, f_32, d_unaryOpList(f32, Ceil) ), // 0x8d - M3OP( "f32.floor", 0, f_32, d_unaryOpList(f32, Floor) ), // 0x8e - M3OP( "f32.trunc", 0, f_32, d_unaryOpList(f32, Trunc) ), // 0x8f - M3OP( "f32.nearest", 0, f_32, d_unaryOpList(f32, Nearest) ), // 0x90 - M3OP( "f32.sqrt", 0, f_32, d_unaryOpList(f32, Sqrt) ), // 0x91 - - M3OP( "f32.add", -1, f_32, d_commutativeBinOpList (f32, Add) ), // 0x92 - M3OP( "f32.sub", -1, f_32, d_binOpList (f32, Subtract) ), // 0x93 - M3OP( "f32.mul", -1, f_32, d_commutativeBinOpList (f32, Multiply) ), // 0x94 - M3OP( "f32.div", -1, f_32, d_binOpList (f32, Divide) ), // 0x95 - M3OP( "f32.min", -1, f_32, d_commutativeBinOpList (f32, Min) ), // 0x96 - M3OP( "f32.max", -1, f_32, d_commutativeBinOpList (f32, Max) ), // 0x97 - M3OP( "f32.copysign", -1, f_32, d_binOpList (f32, CopySign) ), // 0x98 - - M3OP( "f64.abs", 0, f_64, d_unaryOpList(f64, Abs) ), // 0x99 - M3OP( "f64.neg", 0, f_64, d_unaryOpList(f64, Negate) ), // 0x9a - M3OP( "f64.ceil", 0, f_64, d_unaryOpList(f64, Ceil) ), // 0x9b - M3OP( "f64.floor", 0, f_64, d_unaryOpList(f64, Floor) ), // 0x9c - M3OP( "f64.trunc", 0, f_64, d_unaryOpList(f64, Trunc) ), // 0x9d - M3OP( "f64.nearest", 0, f_64, d_unaryOpList(f64, Nearest) ), // 0x9e - M3OP( "f64.sqrt", 0, f_64, d_unaryOpList(f64, Sqrt) ), // 0x9f - - M3OP( "f64.add", -1, f_64, d_commutativeBinOpList (f64, Add) ), // 0xa0 - M3OP( "f64.sub", -1, f_64, d_binOpList (f64, Subtract) ), // 0xa1 - M3OP( "f64.mul", -1, f_64, d_commutativeBinOpList (f64, Multiply) ), // 0xa2 - M3OP( "f64.div", -1, f_64, d_binOpList (f64, Divide) ), // 0xa3 - M3OP( "f64.min", -1, f_64, d_commutativeBinOpList (f64, Min) ), // 0xa4 - M3OP( "f64.max", -1, f_64, d_commutativeBinOpList (f64, Max) ), // 0xa5 - M3OP( "f64.copysign", -1, f_64, d_binOpList (f64, CopySign) ), // 0xa6 + M3OP_F( "f32.abs", 0, f_32, d_unaryOpList(f32, Abs) ), // 0x8b + M3OP_F( "f32.neg", 0, f_32, d_unaryOpList(f32, Negate) ), // 0x8c + M3OP_F( "f32.ceil", 0, f_32, d_unaryOpList(f32, Ceil) ), // 0x8d + M3OP_F( "f32.floor", 0, f_32, d_unaryOpList(f32, Floor) ), // 0x8e + M3OP_F( "f32.trunc", 0, f_32, d_unaryOpList(f32, Trunc) ), // 0x8f + M3OP_F( "f32.nearest", 0, f_32, d_unaryOpList(f32, Nearest) ), // 0x90 + M3OP_F( "f32.sqrt", 0, f_32, d_unaryOpList(f32, Sqrt) ), // 0x91 + + M3OP_F( "f32.add", -1, f_32, d_commutativeBinOpList (f32, Add) ), // 0x92 + M3OP_F( "f32.sub", -1, f_32, d_binOpList (f32, Subtract) ), // 0x93 + M3OP_F( "f32.mul", -1, f_32, d_commutativeBinOpList (f32, Multiply) ), // 0x94 + M3OP_F( "f32.div", -1, f_32, d_binOpList (f32, Divide) ), // 0x95 + M3OP_F( "f32.min", -1, f_32, d_commutativeBinOpList (f32, Min) ), // 0x96 + M3OP_F( "f32.max", -1, f_32, d_commutativeBinOpList (f32, Max) ), // 0x97 + M3OP_F( "f32.copysign", -1, f_32, d_binOpList (f32, CopySign) ), // 0x98 + + M3OP_F( "f64.abs", 0, f_64, d_unaryOpList(f64, Abs) ), // 0x99 + M3OP_F( "f64.neg", 0, f_64, d_unaryOpList(f64, Negate) ), // 0x9a + M3OP_F( "f64.ceil", 0, f_64, d_unaryOpList(f64, Ceil) ), // 0x9b + M3OP_F( "f64.floor", 0, f_64, d_unaryOpList(f64, Floor) ), // 0x9c + M3OP_F( "f64.trunc", 0, f_64, d_unaryOpList(f64, Trunc) ), // 0x9d + M3OP_F( "f64.nearest", 0, f_64, d_unaryOpList(f64, Nearest) ), // 0x9e + M3OP_F( "f64.sqrt", 0, f_64, d_unaryOpList(f64, Sqrt) ), // 0x9f + + M3OP_F( "f64.add", -1, f_64, d_commutativeBinOpList (f64, Add) ), // 0xa0 + M3OP_F( "f64.sub", -1, f_64, d_binOpList (f64, Subtract) ), // 0xa1 + M3OP_F( "f64.mul", -1, f_64, d_commutativeBinOpList (f64, Multiply) ), // 0xa2 + M3OP_F( "f64.div", -1, f_64, d_binOpList (f64, Divide) ), // 0xa3 + M3OP_F( "f64.min", -1, f_64, d_commutativeBinOpList (f64, Min) ), // 0xa4 + M3OP_F( "f64.max", -1, f_64, d_commutativeBinOpList (f64, Max) ), // 0xa5 + M3OP_F( "f64.copysign", -1, f_64, d_binOpList (f64, CopySign) ), // 0xa6 M3OP( "i32.wrap/i64", 0, i_32, d_unaryOpList (i32, Wrap_i64) ), // 0xa7 - M3OP( "i32.trunc_s/f32", 0, i_32, d_convertOpList (i32_Trunc_f32), Compile_Convert ), // 0xa8 - M3OP( "i32.trunc_u/f32", 0, i_32, d_convertOpList (u32_Trunc_f32), Compile_Convert ), // 0xa9 - M3OP( "i32.trunc_s/f64", 0, i_32, d_convertOpList (i32_Trunc_f64), Compile_Convert ), // 0xaa - M3OP( "i32.trunc_u/f64", 0, i_32, d_convertOpList (u32_Trunc_f64), Compile_Convert ), // 0xab + M3OP_F( "i32.trunc_s/f32", 0, i_32, d_convertOpList (i32_Trunc_f32), Compile_Convert ), // 0xa8 + M3OP_F( "i32.trunc_u/f32", 0, i_32, d_convertOpList (u32_Trunc_f32), Compile_Convert ), // 0xa9 + M3OP_F( "i32.trunc_s/f64", 0, i_32, d_convertOpList (i32_Trunc_f64), Compile_Convert ), // 0xaa + M3OP_F( "i32.trunc_u/f64", 0, i_32, d_convertOpList (u32_Trunc_f64), Compile_Convert ), // 0xab M3OP( "i64.extend_s/i32", 0, i_64, d_unaryOpList (i64, Extend_i32) ), // 0xac M3OP( "i64.extend_u/i32", 0, i_64, d_unaryOpList (i64, Extend_u32) ), // 0xad - M3OP( "i64.trunc_s/f32", 0, i_64, d_convertOpList (i64_Trunc_f32), Compile_Convert ), // 0xae - M3OP( "i64.trunc_u/f32", 0, i_64, d_convertOpList (u64_Trunc_f32), Compile_Convert ), // 0xaf - M3OP( "i64.trunc_s/f64", 0, i_64, d_convertOpList (i64_Trunc_f64), Compile_Convert ), // 0xb0 - M3OP( "i64.trunc_u/f64", 0, i_64, d_convertOpList (u64_Trunc_f64), Compile_Convert ), // 0xb1 + M3OP_F( "i64.trunc_s/f32", 0, i_64, d_convertOpList (i64_Trunc_f32), Compile_Convert ), // 0xae + M3OP_F( "i64.trunc_u/f32", 0, i_64, d_convertOpList (u64_Trunc_f32), Compile_Convert ), // 0xaf + M3OP_F( "i64.trunc_s/f64", 0, i_64, d_convertOpList (i64_Trunc_f64), Compile_Convert ), // 0xb0 + M3OP_F( "i64.trunc_u/f64", 0, i_64, d_convertOpList (u64_Trunc_f64), Compile_Convert ), // 0xb1 - M3OP( "f32.convert_s/i32", 0, f_32, d_convertOpList (f32_Convert_i32), Compile_Convert ), // 0xb2 - M3OP( "f32.convert_u/i32", 0, f_32, d_convertOpList (f32_Convert_u32), Compile_Convert ), // 0xb3 - M3OP( "f32.convert_s/i64", 0, f_32, d_convertOpList (f32_Convert_i64), Compile_Convert ), // 0xb4 - M3OP( "f32.convert_u/i64", 0, f_32, d_convertOpList (f32_Convert_u64), Compile_Convert ), // 0xb5 + M3OP_F( "f32.convert_s/i32",0, f_32, d_convertOpList (f32_Convert_i32), Compile_Convert ), // 0xb2 + M3OP_F( "f32.convert_u/i32",0, f_32, d_convertOpList (f32_Convert_u32), Compile_Convert ), // 0xb3 + M3OP_F( "f32.convert_s/i64",0, f_32, d_convertOpList (f32_Convert_i64), Compile_Convert ), // 0xb4 + M3OP_F( "f32.convert_u/i64",0, f_32, d_convertOpList (f32_Convert_u64), Compile_Convert ), // 0xb5 - M3OP( "f32.demote/f64", 0, f_32, d_unaryOpList (f32, Demote_f64) ), // 0xb6 + M3OP_F( "f32.demote/f64", 0, f_32, d_unaryOpList (f32, Demote_f64) ), // 0xb6 - M3OP( "f64.convert_s/i32", 0, f_64, d_convertOpList (f64_Convert_i32), Compile_Convert ), // 0xb7 - M3OP( "f64.convert_u/i32", 0, f_64, d_convertOpList (f64_Convert_u32), Compile_Convert ), // 0xb8 - M3OP( "f64.convert_s/i64", 0, f_64, d_convertOpList (f64_Convert_i64), Compile_Convert ), // 0xb9 - M3OP( "f64.convert_u/i64", 0, f_64, d_convertOpList (f64_Convert_u64), Compile_Convert ), // 0xba + M3OP_F( "f64.convert_s/i32",0, f_64, d_convertOpList (f64_Convert_i32), Compile_Convert ), // 0xb7 + M3OP_F( "f64.convert_u/i32",0, f_64, d_convertOpList (f64_Convert_u32), Compile_Convert ), // 0xb8 + M3OP_F( "f64.convert_s/i64",0, f_64, d_convertOpList (f64_Convert_i64), Compile_Convert ), // 0xb9 + M3OP_F( "f64.convert_u/i64",0, f_64, d_convertOpList (f64_Convert_u64), Compile_Convert ), // 0xba - M3OP( "f64.promote/f32", 0, f_64, d_unaryOpList (f64, Promote_f32) ), // 0xbb + M3OP_F( "f64.promote/f32", 0, f_64, d_unaryOpList (f64, Promote_f32) ), // 0xbb - M3OP( "i32.reinterpret/f32", 0, i_32, d_convertOpList (i32_Reinterpret_f32), Compile_Convert ), // 0xbc - M3OP( "i64.reinterpret/f64", 0, i_64, d_convertOpList (i64_Reinterpret_f64), Compile_Convert ), // 0xbd - M3OP( "f32.reinterpret/i32", 0, f_32, d_convertOpList (f32_Reinterpret_i32), Compile_Convert ), // 0xbe - M3OP( "f64.reinterpret/i64", 0, f_64, d_convertOpList (f64_Reinterpret_i64), Compile_Convert ), // 0xbf + M3OP_F( "i32.reinterpret/f32",0,i_32, d_convertOpList (i32_Reinterpret_f32), Compile_Convert ), // 0xbc + M3OP_F( "i64.reinterpret/f64",0,i_64, d_convertOpList (i64_Reinterpret_f64), Compile_Convert ), // 0xbd + M3OP_F( "f32.reinterpret/i32",0,f_32, d_convertOpList (f32_Reinterpret_i32), Compile_Convert ), // 0xbe + M3OP_F( "f64.reinterpret/i64",0,f_64, d_convertOpList (f64_Reinterpret_i64), Compile_Convert ), // 0xbf M3OP( "i32.extend8_s", 0, i_32, d_unaryOpList (i32, Extend8_s) ), // 0xc0 M3OP( "i32.extend16_s", 0, i_32, d_unaryOpList (i32, Extend16_s) ), // 0xc1 @@ -2123,14 +2142,14 @@ const M3OpInfo c_operations [] = const M3OpInfo c_operationsFC [] = { - M3OP( "i32.trunc_s:sat/f32",0, i_32, d_convertOpList (i32_TruncSat_f32), Compile_Convert ), // 0x00 - M3OP( "i32.trunc_u:sat/f32",0, i_32, d_convertOpList (u32_TruncSat_f32), Compile_Convert ), // 0x01 - M3OP( "i32.trunc_s:sat/f64",0, i_32, d_convertOpList (i32_TruncSat_f64), Compile_Convert ), // 0x02 - M3OP( "i32.trunc_u:sat/f64",0, i_32, d_convertOpList (u32_TruncSat_f64), Compile_Convert ), // 0x03 - M3OP( "i64.trunc_s:sat/f32",0, i_64, d_convertOpList (i64_TruncSat_f32), Compile_Convert ), // 0x04 - M3OP( "i64.trunc_u:sat/f32",0, i_64, d_convertOpList (u64_TruncSat_f32), Compile_Convert ), // 0x05 - M3OP( "i64.trunc_s:sat/f64",0, i_64, d_convertOpList (i64_TruncSat_f64), Compile_Convert ), // 0x06 - M3OP( "i64.trunc_u:sat/f64",0, i_64, d_convertOpList (u64_TruncSat_f64), Compile_Convert ), // 0x07 + M3OP_F( "i32.trunc_s:sat/f32",0, i_32, d_convertOpList (i32_TruncSat_f32), Compile_Convert ), // 0x00 + M3OP_F( "i32.trunc_u:sat/f32",0, i_32, d_convertOpList (u32_TruncSat_f32), Compile_Convert ), // 0x01 + M3OP_F( "i32.trunc_s:sat/f64",0, i_32, d_convertOpList (i32_TruncSat_f64), Compile_Convert ), // 0x02 + M3OP_F( "i32.trunc_u:sat/f64",0, i_32, d_convertOpList (u32_TruncSat_f64), Compile_Convert ), // 0x03 + M3OP_F( "i64.trunc_s:sat/f32",0, i_64, d_convertOpList (i64_TruncSat_f32), Compile_Convert ), // 0x04 + M3OP_F( "i64.trunc_u:sat/f32",0, i_64, d_convertOpList (u64_TruncSat_f32), Compile_Convert ), // 0x05 + M3OP_F( "i64.trunc_s:sat/f64",0, i_64, d_convertOpList (i64_TruncSat_f64), Compile_Convert ), // 0x06 + M3OP_F( "i64.trunc_u:sat/f64",0, i_64, d_convertOpList (u64_TruncSat_f64), Compile_Convert ), // 0x07 # ifdef DEBUG M3OP( "termination", 0, c_m3Type_void ) // for find_operation_info diff --git a/source/m3_compile.h b/source/m3_compile.h index 2ccdde8..7e90276 100644 --- a/source/m3_compile.h +++ b/source/m3_compile.h @@ -152,10 +152,17 @@ const M3OpInfo* GetOpInfo(m3opcode_t opcode) { #define M3OP(...) { __VA_ARGS__ } #define M3OP_RESERVED { "reserved" } #else + // Strip-off name #define M3OP(name, ...) { __VA_ARGS__ } #define M3OP_RESERVED { 0 } #endif +#if d_m3HasFloat + #define M3OP_F M3OP +#else + #define M3OP_F(...) { 0 } +#endif + //----------------------------------------------------------------------------------------------------------------------------------- u16 GetTypeNumSlots (u8 i_type); diff --git a/source/m3_config.h b/source/m3_config.h index c22ca17..9eb94d0 100644 --- a/source/m3_config.h +++ b/source/m3_config.h @@ -21,11 +21,16 @@ # endif # ifndef d_m3MaxFunctionStackHeight -# define d_m3MaxFunctionStackHeight 2000 +# define d_m3MaxFunctionStackHeight 2000 // TODO: comment on upper limit # endif -#define d_m3MaxFunctionSlots 4000 // twice d_m3MaxFunctionStackHeight -#define d_m3MaxConstantTableSize 120 +# ifndef d_m3MaxFunctionSlots +# define d_m3MaxFunctionSlots 4000 // twice d_m3MaxFunctionStackHeight +# endif + +# ifndef d_m3MaxConstantTableSize +# define d_m3MaxConstantTableSize 120 +# endif # ifndef d_m3LogOutput # define d_m3LogOutput 1 @@ -52,31 +57,73 @@ # define d_m3ProfilerSlotMask 0xFFFF # endif + +// profiling and tracing ------------------------------------------------------ + +# ifndef d_m3EnableOpProfiling +# define d_m3EnableOpProfiling 0 // opcode usage counters +# endif + +# ifndef d_m3EnableOpTracing +# define d_m3EnableOpTracing 0 // only works with DEBUG +# endif + + // logging -------------------------------------------------------------------- -// d_m3LogsDefined allows setting logging options through the compiler flags, -// i.e. -DDEBUG -Dd_m3LogsDefined -Dd_m3EnableOpTracing=1 -#ifndef d_m3LogsDefined +# ifndef d_m3LogParse +# define d_m3LogParse 0 // .wasm binary decoding info +# endif + +# ifndef d_m3LogModule +# define d_m3LogModule 0 // wasm module info +# endif + +# ifndef d_m3LogCompile +# define d_m3LogCompile 0 // wasm -> metacode generation phase +# endif + +# ifndef d_m3LogWasmStack +# define d_m3LogWasmStack 0 // dump the wasm stack when pushed or popped +# endif + +# ifndef d_m3LogEmit +# define d_m3LogEmit 0 // metacode generation info +# endif + +# ifndef d_m3LogCodePages +# define d_m3LogCodePages 0 // dump metacode pages when released +# endif + +# ifndef d_m3LogExec +# define d_m3LogExec 0 // low-level interpreter specific logs +# endif + +# ifndef d_m3LogRuntime +# define d_m3LogRuntime 0 // higher-level runtime information +# endif -# define d_m3EnableOpProfiling 0 // profiling or tracing can be used -# define d_m3EnableOpTracing 0 // only works with DEBUG +# ifndef d_m3LogStackTrace +# define d_m3LogStackTrace 0 // dump the call stack when traps occur +# endif -# define d_m3LogParse 0 // .wasm binary decoding info -# define d_m3LogModule 0 // wasm module info -# define d_m3LogCompile 0 // wasm -> metacode generation phase -# define d_m3LogWasmStack 0 // dump the wasm stack when pushed or popped -# define d_m3LogEmit 0 // metacode generation info -# define d_m3LogCodePages 0 // dump metacode pages when released -# define d_m3LogExec 0 // low-level interpreter specific logs -# define d_m3LogRuntime 0 // higher-level runtime information -# define d_m3LogStackTrace 0 // dump the call stack when traps occur -# define d_m3LogNativeStack 0 // track the memory usage of the C-stack +# ifndef d_m3LogNativeStack +# define d_m3LogNativeStack 0 // track the memory usage of the C-stack +# endif -#endif // other ---------------------------------------------------------------------- -//#define d_m3SkipStackCheck -//#define d_m3SkipMemoryBoundsCheck +# ifndef d_m3HasFloat +# define d_m3HasFloat 1 // implement floating point ops +# endif + +# ifndef d_m3SkipStackCheck +# define d_m3SkipStackCheck 0 // skip stack overrun checks +# endif + +# ifndef d_m3SkipMemoryBoundsCheck +# define d_m3SkipMemoryBoundsCheck 0 // skip memory bounds checks +# endif #endif // m3_config_h diff --git a/source/m3_core.c b/source/m3_core.c index f87afa3..aeb34f4 100644 --- a/source/m3_core.c +++ b/source/m3_core.c @@ -274,6 +274,8 @@ M3Result Read_u32 (u32 * o_value, bytes_t * io_bytes, cbytes_t i_end) else return m3Err_wasmUnderrun; } +#if d_m3HasFloat + M3Result Read_f64 (f64 * o_value, bytes_t * io_bytes, cbytes_t i_end) { const u8 * ptr = * io_bytes; @@ -305,6 +307,7 @@ M3Result Read_f32 (f32 * o_value, bytes_t * io_bytes, cbytes_t i_end) else return m3Err_wasmUnderrun; } +#endif M3Result Read_u8 (u8 * o_value, bytes_t * io_bytes, cbytes_t i_end) { diff --git a/source/m3_core.h b/source/m3_core.h index 12dad17..c818277 100644 --- a/source/m3_core.h +++ b/source/m3_core.h @@ -28,8 +28,11 @@ d_m3BeginExternC #if !defined(d_m3ShortTypesDefined) +#if d_m3HasFloat typedef double f64; typedef float f32; +#endif + typedef uint64_t u64; typedef int64_t i64; typedef uint32_t u32; @@ -226,8 +229,10 @@ u32 SizeOfType (u8 i_m3Type); M3Result Read_u64 (u64 * o_value, bytes_t * io_bytes, cbytes_t i_end); M3Result Read_u32 (u32 * o_value, bytes_t * io_bytes, cbytes_t i_end); +#if d_m3HasFloat M3Result Read_f64 (f64 * o_value, bytes_t * io_bytes, cbytes_t i_end); M3Result Read_f32 (f32 * o_value, bytes_t * io_bytes, cbytes_t i_end); +#endif M3Result Read_u8 (u8 * o_value, bytes_t * io_bytes, cbytes_t i_end); M3Result ReadLebUnsigned (u64 * o_value, u32 i_maxNumBits, bytes_t * io_bytes, cbytes_t i_end); diff --git a/source/m3_env.c b/source/m3_env.c index 40ccf9b..9292006 100644 --- a/source/m3_env.c +++ b/source/m3_env.c @@ -781,13 +781,9 @@ _ ((M3Result) Call (i_function->compiled, (m3stack_t) stack, runtime->memo case c_m3Type_f32: fprintf (stderr, "Result: %f\n", *(f32*)(stack)); break; case c_m3Type_f64: fprintf (stderr, "Result: %lf\n", *(f64*)(stack)); break; #else - case c_m3Type_i32: fprintf (stderr, "Result: %u\n", *(u32*)(stack)); break; - case c_m3Type_f32: { - union { u32 u; f32 f; } union32; - union32.f = * (f32 *)(stack); - fprintf (stderr, "Result: %u\n", union32.u ); - break; - } + case c_m3Type_i32: + case c_m3Type_f32: + fprintf (stderr, "Result: %u\n", *(u32*)(stack)); break; case c_m3Type_i64: case c_m3Type_f64: fprintf (stderr, "Result: %" PRIu64 "\n", *(u64*)(stack)); break; diff --git a/source/m3_env.h b/source/m3_env.h index 7ca92a1..eb529c2 100644 --- a/source/m3_env.h +++ b/source/m3_env.h @@ -132,9 +132,12 @@ typedef struct M3Global union { - i64 intValue; + i32 i32Value; + i64 i64Value; +#if d_m3HasFloat f64 f64Value; f32 f32Value; +#endif }; bytes_t initExpr; // wasm code diff --git a/source/m3_exec.c b/source/m3_exec.c index 43e0cab..d032dc6 100644 --- a/source/m3_exec.c +++ b/source/m3_exec.c @@ -201,7 +201,7 @@ d_m3OpDef (Entry) IM3Function function = immediate (IM3Function); -#if defined (d_m3SkipStackCheck) +#if d_m3SkipStackCheck if (true) #else if ((void *) ((m3slot_t *) _sp + function->maxStackSlots) < _mem->maxStack) @@ -339,9 +339,10 @@ d_m3OpDef (PreserveSetSlot_##TYPE) \ d_m3SetRegisterSetSlot (i32, _r0) d_m3SetRegisterSetSlot (i64, _r0) +#if d_m3HasFloat d_m3SetRegisterSetSlot (f32, _fp0) d_m3SetRegisterSetSlot (f64, _fp0) - +#endif d_m3OpDef (CopySlot_32) { diff --git a/source/m3_exec.h b/source/m3_exec.h index 2374466..96ff286 100644 --- a/source/m3_exec.h +++ b/source/m3_exec.h @@ -135,14 +135,14 @@ d_m3Op_i (u32, GreaterThan, > ) d_m3Op_i (u64, GreaterThan, d_m3Op_i (u32, LessThanOrEqual, <=) d_m3Op_i (u64, LessThanOrEqual, <=) d_m3Op_i (u32, GreaterThanOrEqual, >=) d_m3Op_i (u64, GreaterThanOrEqual, >=) -// float +#if d_m3HasFloat d_m3CommutativeCmpOp_f (f32, Equal, ==) d_m3CommutativeCmpOp_f (f64, Equal, ==) d_m3CommutativeCmpOp_f (f32, NotEqual, !=) d_m3CommutativeCmpOp_f (f64, NotEqual, !=) d_m3CompareOp_f (f32, LessThan, < ) d_m3CompareOp_f (f64, LessThan, < ) d_m3CompareOp_f (f32, GreaterThan, > ) d_m3CompareOp_f (f64, GreaterThan, > ) d_m3CompareOp_f (f32, LessThanOrEqual, <=) d_m3CompareOp_f (f64, LessThanOrEqual, <=) d_m3CompareOp_f (f32, GreaterThanOrEqual, >=) d_m3CompareOp_f (f64, GreaterThanOrEqual, >=) - +#endif d_m3CommutativeOp_i (i32, Add, +) d_m3CommutativeOp_i (i64, Add, +) d_m3CommutativeOp_i (i32, Multiply, *) d_m3CommutativeOp_i (i64, Multiply, *) @@ -166,11 +166,12 @@ d_m3CommutativeOp_i (u64, And, &) d_m3CommutativeOp_i (u64, Or, |) d_m3CommutativeOp_i (u64, Xor, ^) +#if d_m3HasFloat d_m3CommutativeOp_f (f32, Add, +) d_m3CommutativeOp_f (f64, Add, +) d_m3CommutativeOp_f (f32, Multiply, *) d_m3CommutativeOp_f (f64, Multiply, *) d_m3Op_f (f32, Subtract, -) d_m3Op_f (f64, Subtract, -) d_m3Op_f (f32, Divide, /) d_m3Op_f (f64, Divide, /) - +#endif d_m3OpFunc_i(u32, Rotl, rotl32) d_m3OpFunc_i(u32, Rotr, rotr32) @@ -187,6 +188,7 @@ d_m3OpMacro_i(i32, Remainder, OP_REM_S, INT32_MIN); d_m3OpMacro_i(u64, Remainder, OP_REM_U); d_m3OpMacro_i(i64, Remainder, OP_REM_S, INT64_MIN); +#if d_m3HasFloat d_m3OpFunc_f(f32, Min, min_f32); d_m3OpFunc_f(f32, Max, max_f32); d_m3OpFunc_f(f64, Min, min_f64); @@ -194,6 +196,7 @@ d_m3OpFunc_f(f64, Max, max_f64); d_m3OpFunc_f(f32, CopySign, copysignf); d_m3OpFunc_f(f64, CopySign, copysign); +#endif // Unary operations // Note: This macro follows the principle of d_m3OpMacro @@ -215,6 +218,7 @@ d_m3Op(TYPE##_##NAME##_s) \ #define d_m3UnaryOp_i(TYPE, NAME, OPERATION) d_m3UnaryMacro( _r0, _r0, TYPE, NAME, M3_UNARY, OPERATION) #define d_m3UnaryOp_f(TYPE, NAME, OPERATION) d_m3UnaryMacro(_fp0, _fp0, TYPE, NAME, M3_UNARY, OPERATION) +#if d_m3HasFloat d_m3UnaryOp_f (f32, Abs, fabsf); d_m3UnaryOp_f (f64, Abs, fabs); d_m3UnaryOp_f (f32, Ceil, ceilf); d_m3UnaryOp_f (f64, Ceil, ceil); d_m3UnaryOp_f (f32, Floor, floorf); d_m3UnaryOp_f (f64, Floor, floor); @@ -222,7 +226,7 @@ d_m3UnaryOp_f (f32, Trunc, truncf); d_m3UnaryOp_f (f64, Trunc, d_m3UnaryOp_f (f32, Sqrt, sqrtf); d_m3UnaryOp_f (f64, Sqrt, sqrt); d_m3UnaryOp_f (f32, Nearest, rintf); d_m3UnaryOp_f (f64, Nearest, rint); d_m3UnaryOp_f (f32, Negate, -); d_m3UnaryOp_f (f64, Negate, -); - +#endif #define OP_EQZ(x) ((x) == 0) @@ -313,6 +317,7 @@ d_m3Op(TYPE##_##NAME##_##FROM##_s_s) \ nextOp (); \ } +#if d_m3HasFloat d_m3TruncMacro(_r0, _fp0, i32, Trunc, f32, OP_I32_TRUNC_F32) d_m3TruncMacro(_r0, _fp0, u32, Trunc, f32, OP_U32_TRUNC_F32) d_m3TruncMacro(_r0, _fp0, i32, Trunc, f64, OP_I32_TRUNC_F64) @@ -332,7 +337,7 @@ d_m3TruncMacro(_r0, _fp0, i64, TruncSat, f32, OP_I64_TRUNC_SAT_F32) d_m3TruncMacro(_r0, _fp0, u64, TruncSat, f32, OP_U64_TRUNC_SAT_F32) d_m3TruncMacro(_r0, _fp0, i64, TruncSat, f64, OP_I64_TRUNC_SAT_F64) d_m3TruncMacro(_r0, _fp0, u64, TruncSat, f64, OP_U64_TRUNC_SAT_F64) - +#endif #define d_m3TypeModifyOp(REG_TO, REG_FROM, TO, NAME, FROM) \ d_m3Op(TO##_##NAME##_##FROM##_r) \ @@ -353,9 +358,10 @@ d_m3TypeModifyOp (_r0, _r0, i64, Extend, i32); d_m3TypeModifyOp (_r0, _r0, i64, Extend, u32); // Float to float +#if d_m3HasFloat d_m3TypeModifyOp (_fp0, _fp0, f32, Demote, f64); d_m3TypeModifyOp (_fp0, _fp0, f64, Promote, f32); - +#endif #define d_m3TypeConvertOp(REG_TO, REG_FROM, TO, NAME, FROM) \ d_m3Op(TO##_##NAME##_##FROM##_r_r) \ @@ -385,6 +391,7 @@ d_m3Op(TO##_##NAME##_##FROM##_s_s) \ } // Int to float +#if d_m3HasFloat d_m3TypeConvertOp (_fp0, _r0, f64, Convert, i32); d_m3TypeConvertOp (_fp0, _r0, f64, Convert, u32); d_m3TypeConvertOp (_fp0, _r0, f64, Convert, i64); @@ -394,7 +401,7 @@ d_m3TypeConvertOp (_fp0, _r0, f32, Convert, i32); d_m3TypeConvertOp (_fp0, _r0, f32, Convert, u32); d_m3TypeConvertOp (_fp0, _r0, f32, Convert, i64); d_m3TypeConvertOp (_fp0, _r0, f32, Convert, u64); - +#endif #define d_m3ReinterpretOp(REG, TO, SRC, FROM) \ d_m3Op(TO##_Reinterpret_##FROM##_r_r) \ @@ -429,11 +436,12 @@ d_m3Op(TO##_Reinterpret_##FROM##_s_s) \ nextOp (); \ } +#if d_m3HasFloat d_m3ReinterpretOp (_r0, i32, _fp0, f32) d_m3ReinterpretOp (_r0, i64, _fp0, f64) d_m3ReinterpretOp (_fp0, f32, _r0, i32) d_m3ReinterpretOp (_fp0, f64, _r0, i64) - +#endif d_m3OpDecl (Loop) d_m3OpDecl (If_r) @@ -531,13 +539,13 @@ d_m3Op (Select_##TYPE##_##LABEL##sr) \ nextOp (); \ } - +#if d_m3HasFloat d_m3Select_f (f32, _fp0, r, _r0) d_m3Select_f (f32, _fp0, s, slot (i32)) d_m3Select_f (f64, _fp0, r, _r0) d_m3Select_f (f64, _fp0, s, slot (i32)) - +#endif d_m3Op (Return) { @@ -691,7 +699,7 @@ d_m3Op (SetGlobal_s64) nextOp (); } - +#if d_m3HasFloat d_m3Op (SetGlobal_f32) { f32 * global = immediate (f32 *); @@ -708,6 +716,7 @@ d_m3Op (SetGlobal_f64) nextOp (); } +#endif d_m3OpDecl (CopySlot_32) @@ -727,7 +736,7 @@ d_m3SetRegisterSetSlotDecl (f32) d_m3SetRegisterSetSlotDecl (f64) -#if defined(d_m3SkipMemoryBoundsCheck) +#if d_m3SkipMemoryBoundsCheck # define m3MemCheck(x) true #else # define m3MemCheck(x) LIKELY(x) @@ -786,8 +795,10 @@ d_m3Op(DEST_TYPE##_Load_##SRC_TYPE##_s) \ #define d_m3Load_i(DEST_TYPE, SRC_TYPE) d_m3Load(_r0, DEST_TYPE, SRC_TYPE) #define d_m3Load_f(DEST_TYPE, SRC_TYPE) d_m3Load(_fp0, DEST_TYPE, SRC_TYPE) +#if d_m3HasFloat d_m3Load_f (f32, f32); d_m3Load_f (f64, f64); +#endif d_m3Load_i (i32, i8); d_m3Load_i (i32, u8); @@ -878,8 +889,10 @@ d_m3Op (TYPE##_Store_##TYPE##_rr) \ #define d_m3Store_i(SRC_TYPE, DEST_TYPE) d_m3Store(_r0, SRC_TYPE, DEST_TYPE) #define d_m3Store_f(SRC_TYPE, DEST_TYPE) d_m3Store(_fp0, SRC_TYPE, DEST_TYPE) d_m3StoreFp (_fp0, SRC_TYPE); +#if d_m3HasFloat d_m3Store_f (f32, f32) d_m3Store_f (f64, f64) +#endif d_m3Store_i (i32, u8) d_m3Store_i (i32, i16) diff --git a/source/m3_exec_defs.h b/source/m3_exec_defs.h index 11588c2..13f96d8 100644 --- a/source/m3_exec_defs.h +++ b/source/m3_exec_defs.h @@ -12,12 +12,24 @@ d_m3BeginExternC +#if d_m3HasFloat + # define d_m3OpSig pc_t _pc, m3stack_t _sp, M3MemoryHeader * _mem, m3reg_t _r0, f64 _fp0 # define d_m3OpArgs _sp, _mem, _r0, _fp0 # define d_m3OpAllArgs _pc, _sp, _mem, _r0, _fp0 # define d_m3OpDefaultArgs 0, 0. # define d_m3ClearRegisters _r0 = 0; _fp0 = 0.; +#else + +# define d_m3OpSig pc_t _pc, m3stack_t _sp, M3MemoryHeader * _mem, m3reg_t _r0 +# define d_m3OpArgs _sp, _mem, _r0 +# define d_m3OpAllArgs _pc, _sp, _mem, _r0 +# define d_m3OpDefaultArgs 0 +# define d_m3ClearRegisters _r0 = 0; + +#endif + # define m3MemData(mem) (u8*)(((M3MemoryHeader*)(mem))+1) # define m3MemRuntime(mem) (((M3MemoryHeader*)(mem))->runtime) # define m3MemInfo(mem) (&(((M3MemoryHeader*)(mem))->runtime->memory)) diff --git a/source/m3_info.c b/source/m3_info.c index 22a4207..d7f2ca8 100644 --- a/source/m3_info.c +++ b/source/m3_info.c @@ -93,10 +93,12 @@ size_t SPrintArg (char * o_string, size_t i_n, m3stack_t i_sp, u8 i_type) len = snprintf (o_string, i_n, "%" PRIi32, * (i32 *) i_sp); else if (i_type == c_m3Type_i64) len = snprintf (o_string, i_n, "%" PRIi64, * (i64 *) i_sp); +#if d_m3HasFloat else if (i_type == c_m3Type_f32) len = snprintf (o_string, i_n, "%f", * (f32 *) i_sp); else if (i_type == c_m3Type_f64) len = snprintf (o_string, i_n, "%lf", * (f64 *) i_sp); +#endif len = M3_MAX (0, len); diff --git a/source/m3_math_utils.h b/source/m3_math_utils.h index e53c652..78cfb65 100644 --- a/source/m3_math_utils.h +++ b/source/m3_math_utils.h @@ -232,6 +232,8 @@ u64 rotr64(u64 n, unsigned c) { /* * Min, Max */ + +#if d_m3HasFloat static inline f32 min_f32(f32 a, f32 b) { if (UNLIKELY(isnan(a) or isnan(b))) return NAN; @@ -259,5 +261,6 @@ f64 max_f64(f64 a, f64 b) { if (UNLIKELY(a == 0 and a == b)) return signbit(a) ? b : a; return a > b ? a : b; } +#endif #endif // m3_math_utils_h