|
|
|
@ -31,6 +31,7 @@
|
|
|
|
|
# define skip_immediate(TYPE) (void)* ((TYPE *) _pc++)
|
|
|
|
|
|
|
|
|
|
# define slot(TYPE) * (TYPE *) (_sp + immediate (i32))
|
|
|
|
|
# define slot_ptr(TYPE) (TYPE *) (_sp + immediate (i32))
|
|
|
|
|
|
|
|
|
|
#define nextOpDirect() ((IM3Operation)(* _pc))(_pc + 1, d_m3OpArgs)
|
|
|
|
|
#define jumpOpDirect(PC) ((IM3Operation)(* PC))( PC + 1, d_m3OpArgs)
|
|
|
|
@ -364,105 +365,60 @@ d_m3OpDecl (If_r)
|
|
|
|
|
d_m3OpDecl (If_s)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d_m3Op (Select_i_ssr)
|
|
|
|
|
{
|
|
|
|
|
i32 condition = (i32) _r0;
|
|
|
|
|
|
|
|
|
|
i64 operand2 = * (_sp + immediate (i32));
|
|
|
|
|
i64 operand1 = * (_sp + immediate (i32));
|
|
|
|
|
|
|
|
|
|
_r0 = (condition) ? operand1 : operand2;
|
|
|
|
|
|
|
|
|
|
return nextOp ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
d_m3Op (Select_i_srs)
|
|
|
|
|
{
|
|
|
|
|
i32 condition = (i32) * (_sp + immediate (i32));
|
|
|
|
|
|
|
|
|
|
i64 operand2 = _r0;
|
|
|
|
|
i64 operand1 = * (_sp + immediate (i32));
|
|
|
|
|
|
|
|
|
|
_r0 = (condition) ? operand1 : operand2;
|
|
|
|
|
|
|
|
|
|
return nextOp ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d_m3Op (Select_i_rss)
|
|
|
|
|
{
|
|
|
|
|
i32 condition = (i32) * (_sp + immediate (i32));
|
|
|
|
|
|
|
|
|
|
i64 operand2 = * (_sp + immediate (i32));
|
|
|
|
|
i64 operand1 = _r0;
|
|
|
|
|
|
|
|
|
|
_r0 = (condition) ? operand1 : operand2;
|
|
|
|
|
|
|
|
|
|
return nextOp ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d_m3Op (Select_i_sss)
|
|
|
|
|
{
|
|
|
|
|
i32 condition = (i32) * (_sp + immediate (i32));
|
|
|
|
|
|
|
|
|
|
i64 operand2 = * (_sp + immediate (i32));
|
|
|
|
|
i64 operand1 = * (_sp + immediate (i32));
|
|
|
|
|
|
|
|
|
|
_r0 = (condition) ? operand1 : operand2;
|
|
|
|
|
|
|
|
|
|
return nextOp ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
d_m3Op (Select_f_ssr)
|
|
|
|
|
{
|
|
|
|
|
i32 condition = (i32) _r0;
|
|
|
|
|
|
|
|
|
|
f64 operand2 = * (f64*)(_sp + immediate (i32));
|
|
|
|
|
f64 operand1 = * (f64*)(_sp + immediate (i32));
|
|
|
|
|
|
|
|
|
|
_fp0 = (condition) ? operand1 : operand2;
|
|
|
|
|
|
|
|
|
|
return nextOp ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
d_m3Op (Select_f_srs)
|
|
|
|
|
{
|
|
|
|
|
i32 condition = (i32) * (_sp + immediate (i32));
|
|
|
|
|
|
|
|
|
|
f64 operand2 = _fp0;
|
|
|
|
|
f64 operand1 = * (f64*)(_sp + immediate (i32));
|
|
|
|
|
|
|
|
|
|
_fp0 = (condition) ? operand1 : operand2;
|
|
|
|
|
|
|
|
|
|
return nextOp ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d_m3Op (Select_f_rss)
|
|
|
|
|
{
|
|
|
|
|
i32 condition = (i32) * (_sp + immediate (i32));
|
|
|
|
|
|
|
|
|
|
f64 operand2 = * (f64*)(_sp + immediate (i32));
|
|
|
|
|
f64 operand1 = _fp0;
|
|
|
|
|
|
|
|
|
|
_fp0 = (condition) ? operand1 : operand2;
|
|
|
|
|
|
|
|
|
|
return nextOp ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d_m3Op (Select_f_sss)
|
|
|
|
|
{
|
|
|
|
|
i32 condition = (i32) * (_sp + immediate (i32));
|
|
|
|
|
#define d_m3Select(TYPE, REG) \
|
|
|
|
|
d_m3Op (Select_##TYPE##_ssr) \
|
|
|
|
|
{ \
|
|
|
|
|
i32 condition = (i32) _r0; \
|
|
|
|
|
\
|
|
|
|
|
TYPE operand2 = slot (TYPE); \
|
|
|
|
|
TYPE operand1 = slot (TYPE); \
|
|
|
|
|
\
|
|
|
|
|
REG = (condition) ? operand1 : operand2; \
|
|
|
|
|
\
|
|
|
|
|
return nextOp (); \
|
|
|
|
|
} \
|
|
|
|
|
\
|
|
|
|
|
d_m3Op (Select_##TYPE##_srs) \
|
|
|
|
|
{ \
|
|
|
|
|
i32 condition = slot (i32); \
|
|
|
|
|
\
|
|
|
|
|
TYPE operand2 = (TYPE) REG; \
|
|
|
|
|
TYPE operand1 = slot (TYPE); \
|
|
|
|
|
\
|
|
|
|
|
REG = (condition) ? operand1 : operand2; \
|
|
|
|
|
\
|
|
|
|
|
return nextOp (); \
|
|
|
|
|
} \
|
|
|
|
|
\
|
|
|
|
|
d_m3Op (Select_##TYPE##_rss) \
|
|
|
|
|
{ \
|
|
|
|
|
i32 condition = slot (i32); \
|
|
|
|
|
\
|
|
|
|
|
TYPE operand2 = slot (TYPE); \
|
|
|
|
|
TYPE operand1 = (TYPE) REG; \
|
|
|
|
|
\
|
|
|
|
|
REG = (condition) ? operand1 : operand2; \
|
|
|
|
|
\
|
|
|
|
|
return nextOp (); \
|
|
|
|
|
} \
|
|
|
|
|
\
|
|
|
|
|
d_m3Op (Select_##TYPE##_sss) \
|
|
|
|
|
{ \
|
|
|
|
|
i32 condition = slot (i32); \
|
|
|
|
|
\
|
|
|
|
|
TYPE operand2 = slot (TYPE); \
|
|
|
|
|
TYPE operand1 = slot (TYPE); \
|
|
|
|
|
\
|
|
|
|
|
REG = (condition) ? operand1 : operand2; \
|
|
|
|
|
\
|
|
|
|
|
return nextOp (); \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
d_m3Select (i32, _r0)
|
|
|
|
|
d_m3Select (i64, _r0)
|
|
|
|
|
d_m3Select (f32, _fp0)
|
|
|
|
|
d_m3Select (f64, _fp0)
|
|
|
|
|
|
|
|
|
|
f64 operand2 = * (f64*)(_sp + immediate (i32));
|
|
|
|
|
f64 operand1 = * (f64*)(_sp + immediate (i32));
|
|
|
|
|
|
|
|
|
|
_fp0 = (condition) ? operand1 : operand2;
|
|
|
|
|
|
|
|
|
|
return nextOp ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
d_m3Op (Return)
|
|
|
|
|
{
|
|
|
|
@ -542,10 +498,11 @@ d_m3OpDecl (Entry)
|
|
|
|
|
d_m3OpDecl (MemCurrent)
|
|
|
|
|
d_m3OpDecl (MemGrow)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d_m3Op (Const)
|
|
|
|
|
{
|
|
|
|
|
u64 constant = immediate (u64);
|
|
|
|
|
i32 offset = immediate (i32);
|
|
|
|
|
u64 constant = immediate (u64);
|
|
|
|
|
i32 offset = immediate (i32);
|
|
|
|
|
* (_sp + offset) = constant;
|
|
|
|
|
|
|
|
|
|
return nextOp ();
|
|
|
|
@ -601,113 +558,88 @@ d_m3Op (SetGlobal_i)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d_m3Op (SetGlobal_f)
|
|
|
|
|
d_m3Op (SetGlobal_f32)
|
|
|
|
|
{
|
|
|
|
|
f64 * global = immediate (f64 *);
|
|
|
|
|
f32 * global = immediate (f32 *);
|
|
|
|
|
* global = _fp0;
|
|
|
|
|
|
|
|
|
|
return nextOp ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d_m3Op (CopySlot)
|
|
|
|
|
{
|
|
|
|
|
u64 * dst = _sp + immediate (i32);
|
|
|
|
|
u64 * src = _sp + immediate (i32);
|
|
|
|
|
|
|
|
|
|
* dst = * src; // printf ("copy: %p <- %" PRIi64 " <- %p\n", dst, * dst, src);
|
|
|
|
|
|
|
|
|
|
return nextOp ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d_m3Op (PreserveCopySlot)
|
|
|
|
|
{
|
|
|
|
|
u64 * dest = _sp + immediate (i32);
|
|
|
|
|
u64 * src = _sp + immediate (i32);
|
|
|
|
|
u64 * preserve = _sp + immediate (i32);
|
|
|
|
|
|
|
|
|
|
* preserve = * dest;
|
|
|
|
|
* dest = * src;
|
|
|
|
|
|
|
|
|
|
return nextOp ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d_m3Op (SetRegister_i)
|
|
|
|
|
{
|
|
|
|
|
i32 offset = immediate (i32);
|
|
|
|
|
|
|
|
|
|
u64 * stack = _sp + offset;
|
|
|
|
|
_r0 = * stack;
|
|
|
|
|
|
|
|
|
|
return nextOp ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d_m3Op (SwapRegister_i)
|
|
|
|
|
d_m3Op (SetGlobal_f64)
|
|
|
|
|
{
|
|
|
|
|
slot (u64) = _r0;
|
|
|
|
|
_r0 = slot (u64);
|
|
|
|
|
f64 * global = immediate (f64 *);
|
|
|
|
|
* global = _fp0;
|
|
|
|
|
|
|
|
|
|
return nextOp ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d_m3Op (SetRegister_f)
|
|
|
|
|
d_m3Op (CopySlot)
|
|
|
|
|
{
|
|
|
|
|
i32 offset = immediate (i32);
|
|
|
|
|
|
|
|
|
|
f64 * stack = (f64 *) _sp + offset;
|
|
|
|
|
_fp0 = * stack;
|
|
|
|
|
u64 * dst = slot_ptr (u64);
|
|
|
|
|
u64 * src = slot_ptr (u64);
|
|
|
|
|
|
|
|
|
|
* dst = * src; // printf ("copy: %p <- %" PRIi64 " <- %p\n", dst, * dst, src);
|
|
|
|
|
|
|
|
|
|
return nextOp ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d_m3Op (SetSlot_i)
|
|
|
|
|
d_m3Op (PreserveCopySlot)
|
|
|
|
|
{
|
|
|
|
|
i32 offset = immediate (i32);
|
|
|
|
|
|
|
|
|
|
// printf ("setslot_i %d\n", offset);
|
|
|
|
|
|
|
|
|
|
u64 * stack = _sp + offset;
|
|
|
|
|
* stack = _r0;
|
|
|
|
|
|
|
|
|
|
return nextOp ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u64 * dest = slot_ptr (u64);
|
|
|
|
|
u64 * src = slot_ptr (u64);
|
|
|
|
|
u64 * preserve = slot_ptr (u64);
|
|
|
|
|
|
|
|
|
|
d_m3Op (PreserveSetSlot_i)
|
|
|
|
|
{
|
|
|
|
|
u64 * stack = (u64 *) _sp + immediate (i32);
|
|
|
|
|
u64 * preserve = (u64 *) _sp + immediate (i32);
|
|
|
|
|
* preserve = * stack;
|
|
|
|
|
* stack = _r0;
|
|
|
|
|
* preserve = * dest;
|
|
|
|
|
* dest = * src;
|
|
|
|
|
|
|
|
|
|
return nextOp ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d_m3Op (SetSlot_f)
|
|
|
|
|
{
|
|
|
|
|
i32 offset = immediate (i32);
|
|
|
|
|
f64 * stack = (f64 *) _sp + offset;
|
|
|
|
|
* stack = _fp0;
|
|
|
|
|
|
|
|
|
|
return nextOp ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d_m3Op (PreserveSetSlot_f)
|
|
|
|
|
{
|
|
|
|
|
f64 * stack = (f64 *) _sp + immediate (i32);
|
|
|
|
|
f64 * preserve = (f64 *) _sp + immediate (i32);
|
|
|
|
|
* preserve = * stack;
|
|
|
|
|
* stack = _fp0;
|
|
|
|
|
|
|
|
|
|
return nextOp ();
|
|
|
|
|
}
|
|
|
|
|
//d_m3Op (SwapRegister_i)
|
|
|
|
|
//{
|
|
|
|
|
// slot (u64) = _r0;
|
|
|
|
|
// _r0 = slot (u64);
|
|
|
|
|
//
|
|
|
|
|
// return nextOp ();
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define d_m3SetRegisterSetSlot(TYPE, REG) \
|
|
|
|
|
d_m3Op (SetRegister_##TYPE) \
|
|
|
|
|
{ \
|
|
|
|
|
REG = slot (TYPE); \
|
|
|
|
|
return nextOp (); \
|
|
|
|
|
} \
|
|
|
|
|
\
|
|
|
|
|
d_m3Op (SetSlot_##TYPE) \
|
|
|
|
|
{ \
|
|
|
|
|
slot (TYPE) = (TYPE) REG; \
|
|
|
|
|
return nextOp (); \
|
|
|
|
|
} \
|
|
|
|
|
\
|
|
|
|
|
d_m3Op (PreserveSetSlot_##TYPE) \
|
|
|
|
|
{ \
|
|
|
|
|
TYPE * stack = slot_ptr (TYPE); \
|
|
|
|
|
TYPE * preserve = slot_ptr (TYPE); \
|
|
|
|
|
\
|
|
|
|
|
* preserve = * stack; \
|
|
|
|
|
* stack = (TYPE) REG; \
|
|
|
|
|
\
|
|
|
|
|
return nextOp (); \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d_m3SetRegisterSetSlot (i32, _r0)
|
|
|
|
|
d_m3SetRegisterSetSlot (i64, _r0)
|
|
|
|
|
d_m3SetRegisterSetSlot (f32, _fp0)
|
|
|
|
|
d_m3SetRegisterSetSlot (f64, _fp0)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define d_outOfBounds return c_m3Err_trapOutOfBoundsMemoryAccess
|
|
|
|
|