d_m3HasFloat - allow disabling float ops

extensions
Volodymyr Shymanskyy 4 years ago
parent 7aad7ea86d
commit bdc5082755

@ -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

@ -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"

@ -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

@ -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);

@ -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

@ -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)
{

@ -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);

@ -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;

@ -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

@ -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)
{

@ -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)

@ -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))

@ -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);

@ -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

Loading…
Cancel
Save