1030 lines
27 KiB
C
1030 lines
27 KiB
C
#ifndef _EEL_GLUE_PORTABLE_H_
|
|
#define _EEL_GLUE_PORTABLE_H_
|
|
|
|
#define GLUE_MOD_IS_64
|
|
|
|
#define DECL_ASMFUNC(x)
|
|
#define GLUE_JMP_TYPE int
|
|
#define GLUE_JMP_SET_OFFSET(endOfInstruction,offset) (((GLUE_JMP_TYPE *)(endOfInstruction))[-1] = (offset))
|
|
|
|
#define GLUE_MAX_FPSTACK_SIZE 64
|
|
#define BIF_FPSTACKUSE(x) (0) // fp stack is not used within functions
|
|
#define BIF_GETFPSTACKUSE(x) (1)
|
|
|
|
enum {
|
|
EEL_BC_NOP=1,
|
|
EEL_BC_RET,
|
|
EEL_BC_JMP_NC, // followed by GLUE_JMP_TYPE
|
|
EEL_BC_JMP_IF_P1_Z,
|
|
EEL_BC_JMP_IF_P1_NZ,
|
|
|
|
EEL_BC_MOV_FPTOP_DV,
|
|
EEL_BC_MOV_P1_DV, // followed by INT_PTR ptr
|
|
EEL_BC_MOV_P2_DV,
|
|
EEL_BC_MOV_P3_DV,
|
|
EEL_BC__RESET_WTP,
|
|
|
|
EEL_BC_PUSH_P1,
|
|
EEL_BC_PUSH_P1PTR_AS_VALUE,
|
|
EEL_BC_POP_P1,
|
|
EEL_BC_POP_P2,
|
|
EEL_BC_POP_P3,
|
|
EEL_BC_POP_VALUE_TO_ADDR,
|
|
|
|
EEL_BC_MOVE_STACK,
|
|
EEL_BC_STORE_P1_TO_STACK_AT_OFFS,
|
|
EEL_BC_MOVE_STACKPTR_TO_P1,
|
|
EEL_BC_MOVE_STACKPTR_TO_P2,
|
|
EEL_BC_MOVE_STACKPTR_TO_P3,
|
|
|
|
EEL_BC_SET_P2_FROM_P1,
|
|
EEL_BC_SET_P3_FROM_P1,
|
|
EEL_BC_COPY_VALUE_AT_P1_TO_ADDR,
|
|
EEL_BC_SET_P1_FROM_WTP,
|
|
EEL_BC_SET_P2_FROM_WTP,
|
|
EEL_BC_SET_P3_FROM_WTP,
|
|
|
|
EEL_BC_POP_FPSTACK_TO_PTR,
|
|
EEL_BC_POP_FPSTACK_TOSTACK,
|
|
|
|
EEL_BC_PUSH_VAL_AT_P1_TO_FPSTACK,
|
|
EEL_BC_PUSH_VAL_AT_P2_TO_FPSTACK,
|
|
EEL_BC_PUSH_VAL_AT_P3_TO_FPSTACK,
|
|
EEL_BC_POP_FPSTACK_TO_WTP,
|
|
EEL_BC_SET_P1_Z,
|
|
EEL_BC_SET_P1_NZ,
|
|
|
|
|
|
EEL_BC_LOOP_LOADCNT,
|
|
EEL_BC_LOOP_END,
|
|
|
|
#if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0
|
|
EEL_BC_WHILE_SETUP,
|
|
#endif
|
|
|
|
EEL_BC_WHILE_BEGIN,
|
|
EEL_BC_WHILE_END,
|
|
EEL_BC_WHILE_CHECK_RV,
|
|
|
|
|
|
|
|
EEL_BC_BNOT,
|
|
EEL_BC_EQUAL,
|
|
EEL_BC_EQUAL_EXACT,
|
|
EEL_BC_NOTEQUAL,
|
|
EEL_BC_NOTEQUAL_EXACT,
|
|
EEL_BC_ABOVE,
|
|
EEL_BC_BELOWEQ,
|
|
|
|
|
|
EEL_BC_ADD,
|
|
EEL_BC_SUB,
|
|
EEL_BC_MUL,
|
|
EEL_BC_DIV,
|
|
EEL_BC_AND,
|
|
EEL_BC_OR,
|
|
EEL_BC_OR0,
|
|
EEL_BC_XOR,
|
|
|
|
EEL_BC_ADD_OP,
|
|
EEL_BC_SUB_OP,
|
|
EEL_BC_ADD_OP_FAST,
|
|
EEL_BC_SUB_OP_FAST,
|
|
EEL_BC_MUL_OP,
|
|
EEL_BC_DIV_OP,
|
|
EEL_BC_MUL_OP_FAST,
|
|
EEL_BC_DIV_OP_FAST,
|
|
EEL_BC_AND_OP,
|
|
EEL_BC_OR_OP,
|
|
EEL_BC_XOR_OP,
|
|
|
|
EEL_BC_UMINUS,
|
|
|
|
EEL_BC_ASSIGN,
|
|
EEL_BC_ASSIGN_FAST,
|
|
EEL_BC_ASSIGN_FAST_FROMFP,
|
|
EEL_BC_ASSIGN_FROMFP,
|
|
EEL_BC_MOD,
|
|
EEL_BC_MOD_OP,
|
|
EEL_BC_SHR,
|
|
EEL_BC_SHL,
|
|
|
|
EEL_BC_SQR,
|
|
EEL_BC_MIN,
|
|
EEL_BC_MAX,
|
|
EEL_BC_MIN_FP,
|
|
EEL_BC_MAX_FP,
|
|
EEL_BC_ABS,
|
|
EEL_BC_SIGN,
|
|
EEL_BC_INVSQRT,
|
|
|
|
EEL_BC_FXCH,
|
|
EEL_BC_POP_FPSTACK,
|
|
|
|
EEL_BC_FCALL,
|
|
EEL_BC_BOOLTOFP,
|
|
EEL_BC_FPTOBOOL,
|
|
EEL_BC_FPTOBOOL_REV,
|
|
|
|
EEL_BC_CFUNC_1PDD,
|
|
EEL_BC_CFUNC_2PDD,
|
|
EEL_BC_CFUNC_2PDDS,
|
|
|
|
EEL_BC_MEGABUF,
|
|
EEL_BC_GMEGABUF,
|
|
|
|
EEL_BC_GENERIC1PARM,
|
|
EEL_BC_GENERIC2PARM,
|
|
EEL_BC_GENERIC3PARM,
|
|
EEL_BC_GENERIC1PARM_RETD,
|
|
EEL_BC_GENERIC2PARM_RETD,
|
|
EEL_BC_GENERIC2XPARM_RETD,
|
|
EEL_BC_GENERIC3PARM_RETD,
|
|
|
|
EEL_BC_USERSTACK_PUSH,
|
|
EEL_BC_USERSTACK_POP,
|
|
EEL_BC_USERSTACK_POPFAST,
|
|
EEL_BC_USERSTACK_PEEK,
|
|
EEL_BC_USERSTACK_PEEK_INT,
|
|
EEL_BC_USERSTACK_PEEK_TOP,
|
|
EEL_BC_USERSTACK_EXCH,
|
|
|
|
EEL_BC_DBG_GETSTACKPTR,
|
|
|
|
};
|
|
|
|
#define BC_DECL(x) static const EEL_BC_TYPE GLUE_##x[] = { EEL_BC_##x };
|
|
#define BC_DECL_JMP(x) static const EEL_BC_TYPE GLUE_##x[1 + sizeof(GLUE_JMP_TYPE) / sizeof(EEL_BC_TYPE)] = { EEL_BC_##x };
|
|
BC_DECL_JMP(JMP_NC)
|
|
BC_DECL_JMP(JMP_IF_P1_Z)
|
|
BC_DECL_JMP(JMP_IF_P1_NZ)
|
|
BC_DECL(RET)
|
|
BC_DECL(FXCH)
|
|
BC_DECL(POP_FPSTACK)
|
|
#define GLUE_POP_FPSTACK_SIZE sizeof(EEL_BC_TYPE)
|
|
BC_DECL(PUSH_P1)
|
|
BC_DECL(PUSH_P1PTR_AS_VALUE)
|
|
BC_DECL(POP_FPSTACK_TOSTACK)
|
|
BC_DECL(POP_FPSTACK_TO_WTP)
|
|
BC_DECL(SET_P1_Z)
|
|
BC_DECL(SET_P1_NZ)
|
|
BC_DECL_JMP(LOOP_LOADCNT)
|
|
|
|
BC_DECL_JMP(LOOP_END)
|
|
|
|
#define GLUE_LOOP_BEGIN_SIZE 0
|
|
#define GLUE_LOOP_BEGIN ((void*)"")
|
|
#define GLUE_LOOP_CLAMPCNT_SIZE 0
|
|
#define GLUE_LOOP_CLAMPCNT ((void*)"")
|
|
|
|
#if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0
|
|
BC_DECL(WHILE_SETUP)
|
|
#define GLUE_WHILE_SETUP_SIZE sizeof(GLUE_WHILE_SETUP)
|
|
BC_DECL_JMP(WHILE_END)
|
|
#else
|
|
#define GLUE_WHILE_SETUP_SIZE 0
|
|
#define GLUE_WHILE_SETUP ((void *)"")
|
|
#define GLUE_WHILE_END_NOJUMP
|
|
BC_DECL(WHILE_END)
|
|
#endif
|
|
|
|
BC_DECL(WHILE_BEGIN);
|
|
BC_DECL_JMP(WHILE_CHECK_RV)
|
|
|
|
#define GLUE_MOV_PX_DIRECTVALUE_SIZE (sizeof(EEL_BC_TYPE) + sizeof(INT_PTR))
|
|
#define GLUE_MOV_PX_DIRECTVALUE_TOSTACK_SIZE GLUE_MOV_PX_DIRECTVALUE_SIZE
|
|
static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wv)
|
|
{
|
|
static const EEL_BC_TYPE tab[] = {
|
|
EEL_BC_MOV_FPTOP_DV,
|
|
EEL_BC_MOV_P1_DV,
|
|
EEL_BC_MOV_P2_DV,
|
|
EEL_BC_MOV_P3_DV,
|
|
};
|
|
*(EEL_BC_TYPE *)b = tab[wv+1];
|
|
*(INT_PTR *) ((char *)b + sizeof(EEL_BC_TYPE)) = v;
|
|
}
|
|
|
|
#define GLUE_FUNC_ENTER_SIZE 0
|
|
#define GLUE_FUNC_LEAVE_SIZE 0
|
|
static const EEL_BC_TYPE GLUE_FUNC_ENTER[1]={-1};
|
|
static const EEL_BC_TYPE GLUE_FUNC_LEAVE[1]={-1};
|
|
|
|
static int GLUE_RESET_WTP(unsigned char *out, void *ptr)
|
|
{
|
|
BC_DECL(_RESET_WTP)
|
|
if (out) memcpy(out,&GLUE__RESET_WTP,sizeof(GLUE__RESET_WTP));
|
|
if (out) *(void **) (out+sizeof(GLUE__RESET_WTP)) = ptr;
|
|
return sizeof(GLUE__RESET_WTP) + sizeof(void *);
|
|
}
|
|
|
|
#define GLUE_POP_PX_SIZE sizeof(EEL_BC_TYPE)
|
|
static void GLUE_POP_PX(void *b, int wv)
|
|
{
|
|
static const EEL_BC_TYPE tab[3] ={
|
|
EEL_BC_POP_P1,
|
|
EEL_BC_POP_P2,
|
|
EEL_BC_POP_P3,
|
|
};
|
|
*(EEL_BC_TYPE *)b = tab[wv];
|
|
}
|
|
|
|
#define GLUE_SET_PX_FROM_P1_SIZE sizeof(EEL_BC_TYPE)
|
|
static void GLUE_SET_PX_FROM_P1(void *b, int wv)
|
|
{
|
|
static const unsigned int tab[3]={
|
|
EEL_BC_NOP,
|
|
EEL_BC_SET_P2_FROM_P1,
|
|
EEL_BC_SET_P3_FROM_P1,
|
|
};
|
|
*(EEL_BC_TYPE *)b = tab[wv];
|
|
}
|
|
|
|
#define GLUE_MOVE_STACK_SIZE (sizeof(EEL_BC_TYPE) + sizeof(int))
|
|
static void GLUE_MOVE_STACK(void *b, int amt)
|
|
{
|
|
*(EEL_BC_TYPE *)b = EEL_BC_MOVE_STACK;
|
|
*(int *)(((EEL_BC_TYPE *)b)+1) = amt;
|
|
}
|
|
#define GLUE_STORE_P1_TO_STACK_AT_OFFS_SIZE(x) (sizeof(EEL_BC_TYPE) + sizeof(int))
|
|
static void GLUE_STORE_P1_TO_STACK_AT_OFFS(void *b, int offs)
|
|
{
|
|
*(EEL_BC_TYPE *)b = EEL_BC_STORE_P1_TO_STACK_AT_OFFS;
|
|
*(int *)(((EEL_BC_TYPE *)b)+1) = offs;
|
|
}
|
|
|
|
#define GLUE_MOVE_PX_STACKPTR_SIZE sizeof(EEL_BC_TYPE)
|
|
static void GLUE_MOVE_PX_STACKPTR_GEN(void *b, int wv)
|
|
{
|
|
static const EEL_BC_TYPE tab[3] = {
|
|
EEL_BC_MOVE_STACKPTR_TO_P1,
|
|
EEL_BC_MOVE_STACKPTR_TO_P2,
|
|
EEL_BC_MOVE_STACKPTR_TO_P3
|
|
};
|
|
*(EEL_BC_TYPE *)b = tab[wv];
|
|
}
|
|
|
|
|
|
static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr)
|
|
{
|
|
if (buf)
|
|
{
|
|
*(EEL_BC_TYPE *)buf = EEL_BC_POP_VALUE_TO_ADDR;
|
|
*(void **) (buf+sizeof(EEL_BC_TYPE)) = destptr;
|
|
}
|
|
return sizeof(EEL_BC_TYPE) + sizeof(void *);
|
|
}
|
|
|
|
static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr)
|
|
{
|
|
if (buf)
|
|
{
|
|
*(EEL_BC_TYPE *)buf = EEL_BC_COPY_VALUE_AT_P1_TO_ADDR;
|
|
*(void **) (buf+sizeof(EEL_BC_TYPE)) = destptr;
|
|
}
|
|
return sizeof(EEL_BC_TYPE) + sizeof(void *);
|
|
}
|
|
|
|
|
|
|
|
|
|
static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv)
|
|
{
|
|
int mv=5;
|
|
char *p=(char*)_p;
|
|
p+=sizeof(EEL_BC_TYPE);
|
|
while (*(INT_PTR*)p && mv-- > 0) p++;
|
|
if (!mv) return (unsigned char *)p;
|
|
|
|
*(INT_PTR *)p = newv;
|
|
return (unsigned char *) p + sizeof(INT_PTR) - sizeof(EEL_BC_TYPE);
|
|
}
|
|
|
|
#define GLUE_SET_PX_FROM_WTP_SIZE sizeof(EEL_BC_TYPE)
|
|
static void GLUE_SET_PX_FROM_WTP(void *b, int wv)
|
|
{
|
|
static const EEL_BC_TYPE tab[3]={
|
|
EEL_BC_SET_P1_FROM_WTP,
|
|
EEL_BC_SET_P2_FROM_WTP,
|
|
EEL_BC_SET_P3_FROM_WTP,
|
|
};
|
|
*(EEL_BC_TYPE *)b = tab[wv];
|
|
}
|
|
|
|
static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr)
|
|
{
|
|
if (buf)
|
|
{
|
|
*(EEL_BC_TYPE *)buf = EEL_BC_POP_FPSTACK_TO_PTR;
|
|
*(void **) (buf+sizeof(EEL_BC_TYPE)) = destptr;
|
|
}
|
|
return sizeof(EEL_BC_TYPE) + sizeof(void *);
|
|
}
|
|
|
|
#define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE sizeof(EEL_BC_TYPE)
|
|
static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv)
|
|
{
|
|
static const EEL_BC_TYPE tab[3] = {
|
|
EEL_BC_PUSH_VAL_AT_P1_TO_FPSTACK,
|
|
EEL_BC_PUSH_VAL_AT_P2_TO_FPSTACK,
|
|
EEL_BC_PUSH_VAL_AT_P3_TO_FPSTACK,
|
|
};
|
|
*(EEL_BC_TYPE *)b = tab[wv];
|
|
}
|
|
|
|
#define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (sizeof(GLUE_POP_FPSTACK_TO_WTP) + GLUE_SET_PX_FROM_WTP_SIZE)
|
|
static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv)
|
|
{
|
|
GLUE_SET_PX_FROM_WTP(buf,wv);
|
|
memcpy(buf + GLUE_SET_PX_FROM_WTP_SIZE,GLUE_POP_FPSTACK_TO_WTP,sizeof(GLUE_POP_FPSTACK_TO_WTP));
|
|
};
|
|
|
|
static unsigned char GLUE_POP_STACK_TO_FPSTACK[1] = { 0 }; // todo
|
|
|
|
#define GLUE_INLINE_LOOPS
|
|
|
|
// end of bytecode glue, now for stubbage
|
|
|
|
|
|
#define BC_DECL_OPCODESZ(n) (1 + ((n)*sizeof(INT_PTR))/sizeof(EEL_BC_TYPE))
|
|
#define BC_DECLASM_N(x,y,n) static EEL_BC_TYPE nseel_asm_##x[1 + BC_DECL_OPCODESZ(n)]={BC_DECL_OPCODESZ(n),EEL_BC_##y };
|
|
#define BC_DECLASM_N2(x,y,n) static EEL_BC_TYPE _asm_##x[1 + BC_DECL_OPCODESZ(n)]={BC_DECL_OPCODESZ(n),EEL_BC_##y };
|
|
#define BC_DECLASM_N_EXPORT(x,y,n) EEL_BC_TYPE _asm_##x[1 + BC_DECL_OPCODESZ(n)]={BC_DECL_OPCODESZ(n),EEL_BC_##y };
|
|
#define BC_DECLASM(x,y) BC_DECLASM_N(x,y,0)
|
|
|
|
BC_DECLASM(band,NOP)
|
|
BC_DECLASM(bor,NOP)
|
|
|
|
BC_DECLASM(bnot,BNOT)
|
|
BC_DECLASM(equal,EQUAL)
|
|
BC_DECLASM(equal_exact,EQUAL_EXACT)
|
|
BC_DECLASM(notequal_exact,NOTEQUAL_EXACT)
|
|
BC_DECLASM(notequal,NOTEQUAL)
|
|
BC_DECLASM(above,ABOVE)
|
|
BC_DECLASM(beloweq,BELOWEQ)
|
|
|
|
BC_DECLASM(add,ADD)
|
|
BC_DECLASM(sub,SUB)
|
|
BC_DECLASM(mul,MUL)
|
|
BC_DECLASM(div,DIV)
|
|
BC_DECLASM(and,AND)
|
|
BC_DECLASM(or,OR)
|
|
BC_DECLASM(or0,OR0)
|
|
BC_DECLASM(xor,XOR)
|
|
|
|
BC_DECLASM(add_op,ADD_OP)
|
|
BC_DECLASM(sub_op,SUB_OP)
|
|
BC_DECLASM(add_op_fast,ADD_OP_FAST)
|
|
BC_DECLASM(sub_op_fast,SUB_OP_FAST)
|
|
BC_DECLASM(mul_op,MUL_OP)
|
|
BC_DECLASM(div_op,DIV_OP)
|
|
BC_DECLASM(mul_op_fast,MUL_OP_FAST)
|
|
BC_DECLASM(div_op_fast,DIV_OP_FAST)
|
|
BC_DECLASM(and_op,AND_OP)
|
|
BC_DECLASM(or_op,OR_OP)
|
|
BC_DECLASM(xor_op,XOR_OP)
|
|
|
|
BC_DECLASM(uminus,UMINUS)
|
|
|
|
BC_DECLASM(assign,ASSIGN)
|
|
BC_DECLASM(assign_fast,ASSIGN_FAST)
|
|
BC_DECLASM(assign_fast_fromfp,ASSIGN_FAST_FROMFP)
|
|
BC_DECLASM(assign_fromfp,ASSIGN_FROMFP)
|
|
BC_DECLASM(mod,MOD)
|
|
BC_DECLASM(mod_op,MOD_OP)
|
|
BC_DECLASM(shr,SHR)
|
|
BC_DECLASM(shl,SHL)
|
|
BC_DECLASM(sqr,SQR)
|
|
|
|
BC_DECLASM(min,MIN)
|
|
BC_DECLASM(max,MAX)
|
|
BC_DECLASM(min_fp,MIN_FP)
|
|
BC_DECLASM(max_fp,MAX_FP)
|
|
BC_DECLASM(abs,ABS)
|
|
BC_DECLASM(sign,SIGN)
|
|
BC_DECLASM(invsqrt,INVSQRT)
|
|
BC_DECLASM(dbg_getstackptr,DBG_GETSTACKPTR)
|
|
|
|
BC_DECLASM(booltofp,BOOLTOFP)
|
|
BC_DECLASM(fptobool,FPTOBOOL)
|
|
BC_DECLASM(fptobool_rev,FPTOBOOL_REV)
|
|
|
|
BC_DECLASM_N(stack_push,USERSTACK_PUSH,3)
|
|
BC_DECLASM_N(stack_pop,USERSTACK_POP,3)
|
|
BC_DECLASM_N(stack_pop_fast,USERSTACK_POPFAST,3)
|
|
BC_DECLASM_N(stack_peek,USERSTACK_PEEK,3)
|
|
|
|
BC_DECLASM_N(stack_peek_int,USERSTACK_PEEK_INT,4)
|
|
|
|
BC_DECLASM_N(stack_peek_top,USERSTACK_PEEK_TOP,1)
|
|
BC_DECLASM_N(stack_exch,USERSTACK_EXCH,1)
|
|
|
|
BC_DECLASM_N(fcall,FCALL,1)
|
|
|
|
BC_DECLASM_N(1pdd,CFUNC_1PDD,1)
|
|
BC_DECLASM_N(2pdd,CFUNC_2PDD,1)
|
|
BC_DECLASM_N(2pdds,CFUNC_2PDDS,1)
|
|
|
|
BC_DECLASM_N2(megabuf,MEGABUF,0)
|
|
BC_DECLASM_N2(gmegabuf,GMEGABUF,2)
|
|
|
|
BC_DECLASM_N_EXPORT(generic1parm,GENERIC1PARM,2)
|
|
BC_DECLASM_N_EXPORT(generic2parm,GENERIC2PARM,2)
|
|
BC_DECLASM_N_EXPORT(generic3parm,GENERIC3PARM,2)
|
|
BC_DECLASM_N_EXPORT(generic1parm_retd,GENERIC1PARM_RETD,2)
|
|
BC_DECLASM_N_EXPORT(generic2parm_retd,GENERIC2PARM_RETD,2)
|
|
BC_DECLASM_N_EXPORT(generic2xparm_retd,GENERIC2XPARM_RETD,3)
|
|
BC_DECLASM_N_EXPORT(generic3parm_retd,GENERIC3PARM_RETD,2)
|
|
|
|
|
|
|
|
static void *GLUE_realAddress(void *fn, int *size)
|
|
{
|
|
EEL_BC_TYPE *rd = (EEL_BC_TYPE *)fn;
|
|
*size = rd[0]*sizeof(EEL_BC_TYPE);
|
|
return rd+1;
|
|
}
|
|
|
|
#define EEL_BC_STACKSIZE (65536)
|
|
|
|
// todo: check for stack overflows! we could determine if this is possible at compile time.
|
|
#define EEL_BC_STACK_POP_SIZE 8
|
|
#define EEL_BC_STACK_PUSH(type, val) (*(type *)(stackptr -= EEL_BC_STACK_POP_SIZE)) = (val)
|
|
#define EEL_BC_STACK_POP() (stackptr += EEL_BC_STACK_POP_SIZE)
|
|
|
|
#define EEL_BC_TRUE ((EEL_F*)(INT_PTR)1)
|
|
|
|
|
|
|
|
|
|
static void GLUE_CALL_CODE(INT_PTR bp, INT_PTR cp, INT_PTR rt)
|
|
{
|
|
char __stack[EEL_BC_STACKSIZE];
|
|
char *iptr = (char*)cp;
|
|
char *stackptr=__stack + EEL_BC_STACKSIZE;
|
|
EEL_F *p1 = NULL, *p2 = NULL, *p3 = NULL, *wtp = (EEL_F*)bp;
|
|
#define fp_top (_fpstacktop[0])
|
|
#define fp_top2 (_fpstacktop[-1])
|
|
#define fp_push(x) *++_fpstacktop=(x)
|
|
#define fp_pop() (*_fpstacktop--)
|
|
#define fp_rewind(x) (_fpstacktop -= (x))
|
|
|
|
EEL_F fpstack[GLUE_MAX_FPSTACK_SIZE];
|
|
EEL_F *_fpstacktop=fpstack-1;
|
|
for (;;)
|
|
{
|
|
EEL_BC_TYPE inst = *(EEL_BC_TYPE *)iptr;
|
|
iptr += sizeof(EEL_BC_TYPE);
|
|
switch (inst)
|
|
{
|
|
case EEL_BC_FXCH:
|
|
{
|
|
EEL_F a = fp_top;
|
|
fp_top=fp_top2;
|
|
fp_top2=a;
|
|
}
|
|
break;
|
|
case EEL_BC_POP_FPSTACK: fp_rewind(1); break;
|
|
case EEL_BC_NOP: break;
|
|
case EEL_BC_RET:
|
|
if (EEL_BC_STACK_POP() > __stack+EEL_BC_STACKSIZE)
|
|
{
|
|
return;
|
|
}
|
|
iptr = *(void **)(stackptr - EEL_BC_STACK_POP_SIZE);
|
|
break;
|
|
case EEL_BC_JMP_NC:
|
|
iptr += sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr;
|
|
break;
|
|
case EEL_BC_JMP_IF_P1_Z:
|
|
iptr += p1 ? sizeof(GLUE_JMP_TYPE) : sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr;
|
|
break;
|
|
case EEL_BC_JMP_IF_P1_NZ:
|
|
iptr += p1 ? sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr : sizeof(GLUE_JMP_TYPE);
|
|
break;
|
|
case EEL_BC_MOV_FPTOP_DV:
|
|
fp_push(**(EEL_F **)iptr);
|
|
iptr += sizeof(void*);
|
|
break;
|
|
case EEL_BC_MOV_P1_DV:
|
|
p1 = *(void **)iptr;
|
|
iptr += sizeof(void*);
|
|
break;
|
|
case EEL_BC_MOV_P2_DV:
|
|
p2 = *(void **)iptr;
|
|
iptr += sizeof(void*);
|
|
break;
|
|
case EEL_BC_MOV_P3_DV:
|
|
p3 = *(void **)iptr;
|
|
iptr += sizeof(void*);
|
|
break;
|
|
case EEL_BC__RESET_WTP:
|
|
wtp = *(void **)iptr;
|
|
iptr += sizeof(void*);
|
|
break;
|
|
case EEL_BC_PUSH_P1:
|
|
EEL_BC_STACK_PUSH(void *, p1);
|
|
break;
|
|
case EEL_BC_PUSH_P1PTR_AS_VALUE:
|
|
EEL_BC_STACK_PUSH(EEL_F, *p1);
|
|
break;
|
|
case EEL_BC_POP_P1:
|
|
p1 = *(EEL_F **) stackptr;
|
|
EEL_BC_STACK_POP();
|
|
break;
|
|
case EEL_BC_POP_P2:
|
|
p2 = *(EEL_F **) stackptr;
|
|
EEL_BC_STACK_POP();
|
|
break;
|
|
case EEL_BC_POP_P3:
|
|
p3 = *(EEL_F **) stackptr;
|
|
EEL_BC_STACK_POP();
|
|
break;
|
|
case EEL_BC_POP_VALUE_TO_ADDR:
|
|
**(EEL_F**)iptr = *(EEL_F *)stackptr;
|
|
EEL_BC_STACK_POP();
|
|
iptr += sizeof(void*);
|
|
break;
|
|
case EEL_BC_MOVE_STACK:
|
|
stackptr += *(int *)iptr;
|
|
iptr += sizeof(int);
|
|
break;
|
|
case EEL_BC_STORE_P1_TO_STACK_AT_OFFS:
|
|
*(void **) (stackptr + *(int *)iptr) = p1;
|
|
iptr += sizeof(int);
|
|
break;
|
|
case EEL_BC_MOVE_STACKPTR_TO_P1:
|
|
p1 = (double *)stackptr;
|
|
break;
|
|
case EEL_BC_MOVE_STACKPTR_TO_P2:
|
|
p2 = (double *)stackptr;
|
|
break;
|
|
case EEL_BC_MOVE_STACKPTR_TO_P3:
|
|
p3 = (double *)stackptr;
|
|
break;
|
|
case EEL_BC_SET_P2_FROM_P1:
|
|
p2=p1;
|
|
break;
|
|
case EEL_BC_SET_P3_FROM_P1:
|
|
p3=p1;
|
|
break;
|
|
case EEL_BC_COPY_VALUE_AT_P1_TO_ADDR:
|
|
**(EEL_F **)iptr = *p1;
|
|
iptr += sizeof(void*);
|
|
break;
|
|
case EEL_BC_SET_P1_FROM_WTP:
|
|
p1 = wtp;
|
|
break;
|
|
case EEL_BC_SET_P2_FROM_WTP:
|
|
p2 = wtp;
|
|
break;
|
|
case EEL_BC_SET_P3_FROM_WTP:
|
|
p3 = wtp;
|
|
break;
|
|
case EEL_BC_POP_FPSTACK_TO_PTR:
|
|
**((EEL_F **)iptr) = fp_pop();
|
|
iptr += sizeof(void *);
|
|
break;
|
|
case EEL_BC_POP_FPSTACK_TOSTACK:
|
|
EEL_BC_STACK_PUSH(EEL_F, fp_pop());
|
|
break;
|
|
case EEL_BC_PUSH_VAL_AT_P1_TO_FPSTACK:
|
|
fp_push(*p1);
|
|
break;
|
|
case EEL_BC_PUSH_VAL_AT_P2_TO_FPSTACK:
|
|
fp_push(*p2);
|
|
break;
|
|
case EEL_BC_PUSH_VAL_AT_P3_TO_FPSTACK:
|
|
fp_push(*p3);
|
|
break;
|
|
case EEL_BC_POP_FPSTACK_TO_WTP:
|
|
*wtp++ = fp_pop();
|
|
break;
|
|
case EEL_BC_SET_P1_Z:
|
|
p1=NULL;
|
|
break;
|
|
case EEL_BC_SET_P1_NZ:
|
|
p1 = EEL_BC_TRUE;
|
|
break;
|
|
|
|
case EEL_BC_LOOP_LOADCNT:
|
|
if ((EEL_BC_STACK_PUSH(int, (int)fp_pop())) < 1)
|
|
{
|
|
EEL_BC_STACK_POP();
|
|
iptr+= sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr;
|
|
}
|
|
else
|
|
{
|
|
iptr += sizeof(GLUE_JMP_TYPE);
|
|
#if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0
|
|
if ((*(int *)stackptr) > NSEEL_LOOPFUNC_SUPPORT_MAXLEN) (*(int *)stackptr) = NSEEL_LOOPFUNC_SUPPORT_MAXLEN;
|
|
#endif
|
|
EEL_BC_STACK_PUSH(void *, wtp);
|
|
}
|
|
break;
|
|
case EEL_BC_LOOP_END:
|
|
wtp = *(void **) (stackptr);
|
|
if (--(*(int *)(stackptr+EEL_BC_STACK_POP_SIZE)) <= 0)
|
|
{
|
|
stackptr += EEL_BC_STACK_POP_SIZE*2;
|
|
iptr += sizeof(GLUE_JMP_TYPE);
|
|
}
|
|
else
|
|
{
|
|
iptr += sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr; // back to the start!
|
|
}
|
|
break;
|
|
|
|
#if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0
|
|
case EEL_BC_WHILE_SETUP:
|
|
EEL_BC_STACK_PUSH(int,NSEEL_LOOPFUNC_SUPPORT_MAXLEN);
|
|
break;
|
|
#endif
|
|
case EEL_BC_WHILE_BEGIN:
|
|
EEL_BC_STACK_PUSH(void *, wtp);
|
|
break;
|
|
case EEL_BC_WHILE_END:
|
|
wtp = *(EEL_F **) stackptr;
|
|
EEL_BC_STACK_POP();
|
|
|
|
#if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0
|
|
if (--(*(int *)stackptr) <= 0)
|
|
{
|
|
EEL_BC_STACK_POP();
|
|
iptr += sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr; // endpt
|
|
}
|
|
else
|
|
{
|
|
iptr += sizeof(GLUE_JMP_TYPE);
|
|
}
|
|
#endif
|
|
break;
|
|
case EEL_BC_WHILE_CHECK_RV:
|
|
if (p1)
|
|
{
|
|
iptr += sizeof(GLUE_JMP_TYPE)+*(GLUE_JMP_TYPE *)iptr; // loop
|
|
}
|
|
else
|
|
{
|
|
// done
|
|
#if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0
|
|
EEL_BC_STACK_POP();
|
|
#endif
|
|
iptr += sizeof(GLUE_JMP_TYPE);
|
|
}
|
|
break;
|
|
case EEL_BC_BNOT:
|
|
p1 = p1 ? NULL : EEL_BC_TRUE;
|
|
break;
|
|
case EEL_BC_EQUAL:
|
|
p1 = fabs(fp_top - fp_top2) < NSEEL_CLOSEFACTOR ? EEL_BC_TRUE : NULL;
|
|
fp_rewind(2);
|
|
break;
|
|
case EEL_BC_EQUAL_EXACT:
|
|
p1 = fp_top == fp_top2 ? EEL_BC_TRUE : NULL;
|
|
fp_rewind(2);
|
|
break;
|
|
case EEL_BC_NOTEQUAL:
|
|
p1 = fabs(fp_top - fp_top2) >= NSEEL_CLOSEFACTOR ? EEL_BC_TRUE : NULL;
|
|
fp_rewind(2);
|
|
break;
|
|
case EEL_BC_NOTEQUAL_EXACT:
|
|
p1 = fp_top != fp_top2 ? EEL_BC_TRUE : NULL;
|
|
fp_rewind(2);
|
|
break;
|
|
case EEL_BC_ABOVE:
|
|
p1 = fp_top < fp_top2 ? EEL_BC_TRUE : NULL;
|
|
fp_rewind(2);
|
|
break;
|
|
case EEL_BC_BELOWEQ:
|
|
p1 = fp_top >= fp_top2 ? EEL_BC_TRUE : NULL;
|
|
fp_rewind(2);
|
|
break;
|
|
|
|
case EEL_BC_ADD:
|
|
fp_top2 += fp_top;
|
|
fp_rewind(1);
|
|
break;
|
|
case EEL_BC_SUB:
|
|
fp_top2 -= fp_top;
|
|
fp_rewind(1);
|
|
break;
|
|
case EEL_BC_MUL:
|
|
fp_top2 *= fp_top;
|
|
fp_rewind(1);
|
|
break;
|
|
case EEL_BC_DIV:
|
|
fp_top2 /= fp_top;
|
|
fp_rewind(1);
|
|
break;
|
|
case EEL_BC_AND:
|
|
fp_top2 = (EEL_F) (((WDL_INT64)fp_top) & (WDL_INT64)(fp_top2));
|
|
fp_rewind(1);
|
|
break;
|
|
case EEL_BC_OR:
|
|
fp_top2 = (EEL_F) (((WDL_INT64)fp_top) | (WDL_INT64)(fp_top2));
|
|
fp_rewind(1);
|
|
break;
|
|
case EEL_BC_OR0:
|
|
fp_top = (EEL_F) ((WDL_INT64)(fp_top));
|
|
break;
|
|
case EEL_BC_XOR:
|
|
fp_top2 = (EEL_F) (((WDL_INT64)fp_top) ^ (WDL_INT64)(fp_top2));
|
|
fp_rewind(1);
|
|
break;
|
|
|
|
case EEL_BC_ADD_OP:
|
|
*(p1 = p2) = denormal_filter_double2(*p2 + fp_pop());
|
|
break;
|
|
case EEL_BC_SUB_OP:
|
|
*(p1 = p2) = denormal_filter_double2(*p2 - fp_pop());
|
|
break;
|
|
case EEL_BC_ADD_OP_FAST:
|
|
*(p1 = p2) += fp_pop();
|
|
break;
|
|
case EEL_BC_SUB_OP_FAST:
|
|
*(p1 = p2) -= fp_pop();
|
|
break;
|
|
case EEL_BC_MUL_OP:
|
|
*(p1 = p2) = denormal_filter_double2(*p2 * fp_pop());
|
|
break;
|
|
case EEL_BC_DIV_OP:
|
|
*(p1 = p2) = denormal_filter_double2(*p2 / fp_pop());
|
|
break;
|
|
case EEL_BC_MUL_OP_FAST:
|
|
*(p1 = p2) *= fp_pop();
|
|
break;
|
|
case EEL_BC_DIV_OP_FAST:
|
|
*(p1 = p2) /= fp_pop();
|
|
break;
|
|
case EEL_BC_AND_OP:
|
|
p1 = p2;
|
|
*p2 = (EEL_F) (((WDL_INT64)*p2) & (WDL_INT64)fp_pop());
|
|
break;
|
|
case EEL_BC_OR_OP:
|
|
p1 = p2;
|
|
*p2 = (EEL_F) (((WDL_INT64)*p2) | (WDL_INT64)fp_pop());
|
|
break;
|
|
case EEL_BC_XOR_OP:
|
|
p1 = p2;
|
|
*p2 = (EEL_F) (((WDL_INT64)*p2) ^ (WDL_INT64)fp_pop());
|
|
break;
|
|
case EEL_BC_UMINUS:
|
|
fp_top = -fp_top;
|
|
break;
|
|
case EEL_BC_ASSIGN:
|
|
*p2 = denormal_filter_double2(*p1);
|
|
p1 = p2;
|
|
break;
|
|
case EEL_BC_ASSIGN_FAST:
|
|
*p2 = *p1;
|
|
p1 = p2;
|
|
break;
|
|
case EEL_BC_ASSIGN_FAST_FROMFP:
|
|
*p2 = fp_pop();
|
|
p1 = p2;
|
|
break;
|
|
case EEL_BC_ASSIGN_FROMFP:
|
|
*p2 = denormal_filter_double2(fp_pop());
|
|
p1 = p2;
|
|
break;
|
|
case EEL_BC_MOD:
|
|
{
|
|
int a = (int) fabs(fp_pop());
|
|
fp_top = a ? (EEL_F) (((WDL_INT64)fabs(fp_top)) % a) : 0.0;
|
|
}
|
|
break;
|
|
case EEL_BC_MOD_OP:
|
|
{
|
|
int a = (int) fabs(fp_pop());
|
|
*p2 = a ? (EEL_F) (((WDL_INT64)fabs(*p2)) % a) : 0.0;
|
|
p1=p2;
|
|
|
|
}
|
|
break;
|
|
case EEL_BC_SHR:
|
|
fp_top2 = (EEL_F) (((int)fp_top2) >> (int)fp_top);
|
|
fp_rewind(1);
|
|
break;
|
|
case EEL_BC_SHL:
|
|
fp_top2 = (EEL_F) (((int)fp_top2) << (int)fp_top);
|
|
fp_rewind(1);
|
|
break;
|
|
case EEL_BC_SQR:
|
|
fp_top *= fp_top;
|
|
break;
|
|
case EEL_BC_MIN:
|
|
if (*p1 > *p2) p1 = p2;
|
|
break;
|
|
case EEL_BC_MAX:
|
|
if (*p1 < *p2) p1 = p2;
|
|
break;
|
|
case EEL_BC_MIN_FP:
|
|
{
|
|
EEL_F a=fp_pop();
|
|
if (a<fp_top) fp_top=a;
|
|
}
|
|
break;
|
|
case EEL_BC_MAX_FP:
|
|
{
|
|
EEL_F a=fp_pop();
|
|
if (a>fp_top) fp_top=a;
|
|
}
|
|
break;
|
|
case EEL_BC_ABS:
|
|
fp_top = fabs(fp_top);
|
|
break;
|
|
case EEL_BC_SIGN:
|
|
if (fp_top<0.0) fp_top=-1.0;
|
|
else if (fp_top>0.0) fp_top=1.0;
|
|
break;
|
|
case EEL_BC_DBG_GETSTACKPTR:
|
|
fp_top = (int)(stackptr - __stack);
|
|
break;
|
|
case EEL_BC_INVSQRT:
|
|
{
|
|
float y = (float)fp_top;
|
|
int i = 0x5f3759df - ( (* (int *) &y) >> 1 );
|
|
y = *(float *) &i;
|
|
fp_top = y * ( 1.5F - ( (fp_top * 0.5) * y * y ) );
|
|
}
|
|
break;
|
|
case EEL_BC_FCALL:
|
|
{
|
|
char *newiptr = *(char **)iptr;
|
|
EEL_BC_STACK_PUSH(void *, (iptr += sizeof(void *)));
|
|
iptr = newiptr;
|
|
}
|
|
break;
|
|
case EEL_BC_BOOLTOFP:
|
|
fp_push(p1 ? 1.0 : 0.0);
|
|
break;
|
|
case EEL_BC_FPTOBOOL:
|
|
p1 = fabs(fp_pop()) >= NSEEL_CLOSEFACTOR ? EEL_BC_TRUE : NULL;
|
|
break;
|
|
case EEL_BC_FPTOBOOL_REV:
|
|
p1 = fabs(fp_pop()) < NSEEL_CLOSEFACTOR ? EEL_BC_TRUE : NULL;
|
|
break;
|
|
|
|
case EEL_BC_CFUNC_1PDD:
|
|
{
|
|
double (*f)(double) = *(double (**)(double)) iptr;
|
|
fp_top = f(fp_top);
|
|
iptr += sizeof(void *);
|
|
}
|
|
break;
|
|
case EEL_BC_CFUNC_2PDD:
|
|
{
|
|
double (*f)(double,double) = *(double (**)(double,double))iptr;
|
|
fp_top2 = f(fp_top2,fp_top);
|
|
fp_rewind(1);
|
|
iptr += sizeof(void *);
|
|
}
|
|
break;
|
|
case EEL_BC_CFUNC_2PDDS:
|
|
{
|
|
double (*f)(double,double) = *(double (**)(double,double))iptr;
|
|
*p2 = f(*p2,fp_pop());
|
|
p1 = p2;
|
|
iptr += sizeof(void *);
|
|
}
|
|
break;
|
|
|
|
case EEL_BC_MEGABUF:
|
|
{
|
|
unsigned int idx=(unsigned int) (fp_pop() + NSEEL_CLOSEFACTOR);
|
|
EEL_F **f = (EEL_F **)rt,*f2;
|
|
p1 = (idx < NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK && (f2=f[idx/NSEEL_RAM_ITEMSPERBLOCK])) ?
|
|
(f2 + (idx&(NSEEL_RAM_ITEMSPERBLOCK-1))) :
|
|
__NSEEL_RAMAlloc((void*)rt,idx);
|
|
}
|
|
break;
|
|
case EEL_BC_GMEGABUF:
|
|
{
|
|
p1 = __NSEEL_RAMAllocGMEM(*(EEL_F ****)iptr,(int) (fp_pop() + NSEEL_CLOSEFACTOR));
|
|
iptr += sizeof(void *)*2; // also includes ptr to __NSEEL_RAMAllocGMEM, which we ignore
|
|
}
|
|
break;
|
|
case EEL_BC_GENERIC1PARM:
|
|
{
|
|
EEL_F *(*f)(void *,EEL_F*) = *(EEL_F *(**)(void *, EEL_F *)) (iptr+sizeof(void *));
|
|
p1 = f(*(void **)iptr,p1);
|
|
iptr += sizeof(void *)*2;
|
|
}
|
|
break;
|
|
case EEL_BC_GENERIC2PARM:
|
|
{
|
|
EEL_F *(*f)(void *,EEL_F*,EEL_F*) = *(EEL_F *(**)(void *, EEL_F *, EEL_F *)) (iptr+sizeof(void *));
|
|
p1 = f(*(void **)iptr,p2, p1);
|
|
iptr += sizeof(void *)*2;
|
|
}
|
|
break;
|
|
case EEL_BC_GENERIC3PARM:
|
|
{
|
|
EEL_F *(*f)(void *,EEL_F*,EEL_F*,EEL_F*) = *(EEL_F *(**)(void *, EEL_F *, EEL_F *, EEL_F *)) (iptr+sizeof(void *));
|
|
p1 = f(*(void **)iptr,p3, p2, p1);
|
|
iptr += sizeof(void *)*2;
|
|
}
|
|
break;
|
|
case EEL_BC_GENERIC1PARM_RETD:
|
|
{
|
|
EEL_F (*f)(void *,EEL_F*) = *(EEL_F (**)(void *, EEL_F *)) (iptr+sizeof(void *));
|
|
fp_push(f(*(void **)iptr,p1));
|
|
iptr += sizeof(void *)*2;
|
|
}
|
|
break;
|
|
case EEL_BC_GENERIC2PARM_RETD:
|
|
{
|
|
EEL_F (*f)(void *,EEL_F*,EEL_F*) = *(EEL_F (**)(void *, EEL_F *, EEL_F *)) (iptr+sizeof(void *));
|
|
fp_push(f(*(void **)iptr,p2, p1));
|
|
iptr += sizeof(void *)*2;
|
|
}
|
|
break;
|
|
case EEL_BC_GENERIC2XPARM_RETD:
|
|
{
|
|
EEL_F (*f)(void *,void *,EEL_F*,EEL_F*) = *(EEL_F (**)(void *, void *, EEL_F *, EEL_F *)) (iptr+2*sizeof(void *));
|
|
fp_push(f(*(void **)iptr,((void **)iptr)[1],p2, p1));
|
|
iptr += sizeof(void *)*3;
|
|
}
|
|
break;
|
|
case EEL_BC_GENERIC3PARM_RETD:
|
|
{
|
|
EEL_F (*f)(void *,EEL_F*,EEL_F*,EEL_F*) = *(EEL_F (**)(void *, EEL_F *, EEL_F *, EEL_F *)) (iptr+sizeof(void *));
|
|
fp_push(f(*(void **)iptr,p3, p2, p1));
|
|
iptr += sizeof(void *)*2;
|
|
}
|
|
break;
|
|
|
|
case EEL_BC_USERSTACK_PUSH:
|
|
{
|
|
UINT_PTR *sptr = *(UINT_PTR **)iptr;
|
|
(*sptr) += 8;
|
|
(*sptr) &= *(UINT_PTR*)(iptr+sizeof(void *));
|
|
(*sptr) |= *(UINT_PTR*)(iptr+2*sizeof(void *));
|
|
*(EEL_F *)*sptr = *p1;
|
|
}
|
|
iptr += sizeof(void*)*3;
|
|
break;
|
|
case EEL_BC_USERSTACK_POP:
|
|
{
|
|
UINT_PTR *sptr = *(UINT_PTR **)iptr;
|
|
*p1 = *(EEL_F *)*sptr;
|
|
(*sptr) -= 8;
|
|
(*sptr) &= *(UINT_PTR*)(iptr+sizeof(void *));
|
|
(*sptr) |= *(UINT_PTR*)(iptr+2*sizeof(void *));
|
|
}
|
|
iptr += sizeof(void*)*3;
|
|
break;
|
|
case EEL_BC_USERSTACK_POPFAST:
|
|
{
|
|
UINT_PTR *sptr = *(UINT_PTR **)iptr;
|
|
p1 = (EEL_F *)*sptr;
|
|
(*sptr) -= 8;
|
|
(*sptr) &= *(UINT_PTR*)(iptr+sizeof(void *));
|
|
(*sptr) |= *(UINT_PTR*)(iptr+2*sizeof(void *));
|
|
}
|
|
iptr += sizeof(void*)*3;
|
|
break;
|
|
case EEL_BC_USERSTACK_PEEK:
|
|
{
|
|
UINT_PTR sptr = **(UINT_PTR **)iptr;
|
|
sptr -= sizeof(EEL_F) * (int)(fp_pop());
|
|
sptr &= *(UINT_PTR*)(iptr+sizeof(void *));
|
|
sptr |= *(UINT_PTR*)(iptr+2*sizeof(void *));
|
|
p1 = (EEL_F *)sptr;
|
|
}
|
|
iptr += sizeof(void*)*3;
|
|
break;
|
|
case EEL_BC_USERSTACK_PEEK_INT:
|
|
{
|
|
UINT_PTR sptr = **(UINT_PTR **)iptr;
|
|
sptr -= *(UINT_PTR*)(iptr+sizeof(void*));
|
|
sptr &= *(UINT_PTR*)(iptr+2*sizeof(void *));
|
|
sptr |= *(UINT_PTR*)(iptr+3*sizeof(void *));
|
|
p1 = (EEL_F *)sptr;
|
|
}
|
|
iptr += sizeof(void*)*4;
|
|
break;
|
|
case EEL_BC_USERSTACK_PEEK_TOP:
|
|
p1 = **(EEL_F ***)iptr;
|
|
iptr += sizeof(void*);
|
|
break;
|
|
case EEL_BC_USERSTACK_EXCH:
|
|
{
|
|
EEL_F *p=**(EEL_F ***)iptr;
|
|
EEL_F a=*p;
|
|
*p=*p1;
|
|
*p1=a;
|
|
}
|
|
iptr += sizeof(void*);
|
|
break;
|
|
}
|
|
}
|
|
#undef fp_top
|
|
#undef fp_top2
|
|
#undef fp_pop
|
|
#undef fp_push
|
|
};
|
|
|
|
#endif
|