Files
tlib/oversampling/WDL/eel2/glue_port.h
2024-05-24 13:28:31 +02:00

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