mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-12-22 15:45:54 +01:00
1566 lines
35 KiB
C
1566 lines
35 KiB
C
#if defined(__APPLE__)
|
|
#define SAVE_STACK "pushl %ebp\nmovl %esp, %ebp\nandl $-16, %esp\n"
|
|
#define RESTORE_STACK "leave\n"
|
|
#else
|
|
#define SAVE_STACK
|
|
#define RESTORE_STACK
|
|
#endif
|
|
|
|
/* note: only EEL_F_SIZE=8 is now supported (no float EEL_F's) */
|
|
|
|
void nseel_asm_1pdd(void)
|
|
{
|
|
__asm__(
|
|
SAVE_STACK
|
|
#ifdef TARGET_X64
|
|
"movq (%eax), %xmm0\n"
|
|
"subl $128, %rsp\n"
|
|
"movl $0xffffffff, %edi\n"
|
|
#ifdef AMD64ABI
|
|
"movl %rsi, %r15\n"
|
|
"call *%edi\n"
|
|
"movl %r15, %rsi\n"
|
|
"movq xmm0, (%r15)\n"
|
|
#else
|
|
"call *%edi\n"
|
|
"movq xmm0, (%esi)\n"
|
|
#endif
|
|
"addl $128, %rsp\n"
|
|
#else
|
|
"subl $8, %esp\n" /* keep stack aligned */
|
|
"pushl 4(%eax)\n" /* push parameter */
|
|
"pushl (%eax)\n" /* push the rest of the parameter */
|
|
"movl $0xffffffff, %edi\n"
|
|
"call *%edi\n"
|
|
"fstpl (%esi)\n" /* store result */
|
|
"addl $16, %esp\n"
|
|
#endif
|
|
"movl %esi, %eax\n" /* set return value */
|
|
"addl $8, %esi\n" /* advance worktab ptr */
|
|
RESTORE_STACK
|
|
);
|
|
}
|
|
void nseel_asm_1pdd_end(void){}
|
|
|
|
void nseel_asm_2pdd(void)
|
|
{
|
|
__asm__(
|
|
SAVE_STACK
|
|
#ifdef TARGET_X64
|
|
"movq (%eax), xmm1\n"
|
|
"movq (%edi), xmm0\n"
|
|
"subl $128, %rsp\n"
|
|
"movl $0xffffffff, %edi\n"
|
|
#ifdef AMD64ABI
|
|
"movl %rsi, %r15\n"
|
|
"call *%edi\n"
|
|
"movl %r15, %rsi\n"
|
|
"movq xmm0, (%r15)\n"
|
|
#else
|
|
"call *%edi\n"
|
|
"movq xmm0, (%esi)\n"
|
|
#endif
|
|
"addl $128, %rsp\n"
|
|
#else
|
|
"pushl 4(%eax)\n" /* push parameter */
|
|
"pushl (%eax)\n" /* push the rest of the parameter */
|
|
"pushl 4(%edi)\n" /* push parameter */
|
|
"pushl (%edi)\n" /* push the rest of the parameter */
|
|
"movl $0xffffffff, %edi\n"
|
|
"call *%edi\n"
|
|
"fstpl (%esi)\n" /* store result */
|
|
"addl $16, %esp\n"
|
|
#endif
|
|
"movl %esi, %eax\n" /* set return value */
|
|
"addl $8, %esi\n" /* advance worktab ptr */
|
|
RESTORE_STACK
|
|
);
|
|
}
|
|
void nseel_asm_2pdd_end(void){}
|
|
|
|
void nseel_asm_2pdds(void)
|
|
{
|
|
__asm__(
|
|
SAVE_STACK
|
|
#ifdef TARGET_X64
|
|
"movq (%eax), xmm1\n"
|
|
"movq (%edi), xmm0\n"
|
|
"subl $128, %rsp\n"
|
|
"movl $0xffffffff, %eax\n"
|
|
#ifdef AMD64ABI
|
|
"movl %rsi, %r15\n"
|
|
"movl %rdi, %r14\n"
|
|
"call *%eax\n"
|
|
"movl %r15, %rsi\n"
|
|
"movq xmm0, (%r14)\n"
|
|
"movl %r14, %rax\n" /* set return value */
|
|
#else
|
|
"call *%eax\n"
|
|
"movq xmm0, (%edi)\n"
|
|
"movl %edi, %eax\n" /* set return value */
|
|
#endif
|
|
"subl $128, %rsp\n"
|
|
#else
|
|
"pushl 4(%eax)\n" /* push parameter */
|
|
"pushl (%eax)\n" /* push the rest of the parameter */
|
|
"pushl 4(%edi)\n" /* push parameter */
|
|
"pushl (%edi)\n" /* push the rest of the parameter */
|
|
"movl $0xffffffff, %eax\n"
|
|
"call *%eax\n"
|
|
"fstpl (%edi)\n" /* store result */
|
|
"addl $16, %esp\n"
|
|
"movl %edi, %eax\n" /* set return value */
|
|
#endif
|
|
RESTORE_STACK
|
|
);
|
|
}
|
|
void nseel_asm_2pdds_end(void){}
|
|
|
|
void nseel_asm_2pp(void)
|
|
{
|
|
__asm__(
|
|
SAVE_STACK
|
|
#ifdef TARGET_X64
|
|
|
|
#ifdef AMD64ABI
|
|
"movl %rsi, %r15\n"
|
|
/* rdi is first parameter */
|
|
"movl %rax, %rsi\n"
|
|
"subl $128, %rsp\n"
|
|
"movl $0xffffffff, %eax\n"
|
|
"call *%eax\n"
|
|
"movl %r15, %rsi\n"
|
|
"movq xmm0, (%r15)\n"
|
|
#else
|
|
"movl %edi, %ecx\n"
|
|
"movl %eax, %edx\n"
|
|
"subl $128, %rsp\n"
|
|
"movl $0xffffffff, %edi\n"
|
|
"call *%edi\n"
|
|
"movq xmm0, (%esi)\n"
|
|
#endif
|
|
"addl $128, %rsp\n"
|
|
#else
|
|
"subl $8, %esp\n" /* keep stack aligned */
|
|
"pushl %eax\n" /* push parameter */
|
|
"pushl %edi\n" /* push second parameter */
|
|
"movl $0xffffffff, %edi\n"
|
|
"call *%edi\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n" /* store result */
|
|
"addl $16, %esp\n"
|
|
#endif
|
|
"movl %esi, %eax\n" /* set return value */
|
|
"addl $" EEL_F_SSTR ", %esi\n" /* advance worktab ptr */
|
|
RESTORE_STACK
|
|
);
|
|
}
|
|
void nseel_asm_2pp_end(void) {}
|
|
|
|
|
|
void nseel_asm_1pp(void)
|
|
{
|
|
__asm__(
|
|
SAVE_STACK
|
|
#ifdef TARGET_X64
|
|
#ifdef AMD64ABI
|
|
"movl %rsi, %r15\n"
|
|
"movl %eax, %edi\n"
|
|
"subl $128, %rsp\n"
|
|
"movl $0xffffffff, %rax\n"
|
|
"call *%rax\n"
|
|
"movl %r15, %rsi\n"
|
|
"movq xmm0, (%r15)\n"
|
|
#else
|
|
"movl %eax, %ecx\n"
|
|
"subl $128, %rsp\n"
|
|
"movl $0xffffffff, %edi\n"
|
|
"call *%edi\n"
|
|
"movq xmm0, (%esi)\n"
|
|
#endif
|
|
"addl $128, %rsp\n"
|
|
#else
|
|
"subl $12, %esp\n" /* keep stack aligned */
|
|
"pushl %eax\n" /* push parameter */
|
|
"movl $0xffffffff, %edi\n"
|
|
"call *%edi\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n" /* store result */
|
|
"addl $16, %esp\n"
|
|
#endif
|
|
"movl %esi, %eax\n" /* set return value */
|
|
"addl $" EEL_F_SSTR ", %esi\n" /* advance worktab ptr */
|
|
RESTORE_STACK
|
|
);
|
|
}
|
|
void nseel_asm_1pp_end(void){}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
// do nothing, eh
|
|
void nseel_asm_exec2(void)
|
|
{
|
|
__asm__(
|
|
""
|
|
);
|
|
}
|
|
void nseel_asm_exec2_end(void) { }
|
|
|
|
|
|
|
|
void nseel_asm_invsqrt(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"movl $0x5f3759df, %edx\n"
|
|
"fsts (%esi)\n"
|
|
#ifdef TARGET_X64
|
|
"movl 0xffffffff, %rax\n"
|
|
"subl %ecx, %ecx\n"
|
|
"fmul" EEL_F_SUFFIX " (%rax)\n"
|
|
#else
|
|
"fmul" EEL_F_SUFFIX " (0xffffffff)\n"
|
|
#endif
|
|
"movl (%esi), %ecx\n"
|
|
"sarl $1, %ecx\n"
|
|
"subl %ecx, %edx\n"
|
|
"movl %edx, (%esi)\n"
|
|
"fmuls (%esi)\n"
|
|
"fmuls (%esi)\n"
|
|
#ifdef TARGET_X64
|
|
"movl 0xffffffff, %rax\n"
|
|
"fadd" EEL_F_SUFFIX " (%rax)\n"
|
|
#else
|
|
"fadd" EEL_F_SUFFIX " (0xffffffff)\n"
|
|
#endif
|
|
"fmuls (%esi)\n"
|
|
"movl %esi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_invsqrt_end(void) {}
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_sin(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fsin\n"
|
|
"movl %esi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_sin_end(void) {}
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_cos(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fcos\n"
|
|
"movl %esi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_cos_end(void) {}
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_tan(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fptan\n"
|
|
"movl %esi, %eax\n"
|
|
"fstp %st(0)\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_tan_end(void) {}
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_sqr(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fmul %st(0), %st(0)\n"
|
|
"movl %esi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_sqr_end(void) {}
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_sqrt(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fabs\n"
|
|
"fsqrt\n"
|
|
"movl %esi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_sqrt_end(void) {}
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_log(void)
|
|
{
|
|
__asm__(
|
|
"fldln2\n"
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"movl %esi, %eax\n"
|
|
"fyl2x\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_log_end(void) {}
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_log10(void)
|
|
{
|
|
__asm__(
|
|
"fldlg2\n"
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"movl %esi, %eax\n"
|
|
"fyl2x\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
|
|
);
|
|
}
|
|
void nseel_asm_log10_end(void) {}
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_abs(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fabs\n"
|
|
"movl %esi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_abs_end(void) {}
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_assign(void)
|
|
{
|
|
#ifdef TARGET_X64
|
|
|
|
__asm__(
|
|
"movll (%rax), %rdx\n"
|
|
"movll %rdx, %rcx\n"
|
|
"shrl $32, %rdx\n"
|
|
"andl $0x7FF00000, %edx\n"
|
|
"jz 1f\n"
|
|
"cmpl $0x7FF00000, %edx\n"
|
|
"je 1f\n"
|
|
"jmp 0f\n"
|
|
"1:\n"
|
|
"subl %rcx, %rcx\n"
|
|
"0:\n"
|
|
"movll %rcx, (%edi)\n"
|
|
);
|
|
|
|
#else
|
|
|
|
|
|
#if EEL_F_SIZE == 8
|
|
__asm__(
|
|
"movl 4(%eax), %edx\n"
|
|
"movl (%eax), %ecx\n"
|
|
"andl $0x7ff00000, %edx\n"
|
|
"jz 1f\n" // if exponent=zero, zero
|
|
"cmpl $0x7ff00000, %edx\n"
|
|
"je 1f\n" // if exponent=all 1s, zero
|
|
"movl 4(%eax), %edx\n" // reread
|
|
"jmp 0f\n"
|
|
"1:\n"
|
|
"subl %ecx, %ecx\n"
|
|
"subl %edx, %edx\n"
|
|
"0:\n"
|
|
"movl %ecx, (%edi)\n"
|
|
"movl %edx, 4(%edi)\n"
|
|
);
|
|
#else
|
|
__asm__(
|
|
"movl (%eax), %ecx\n"
|
|
"movl %ecx, (%edi)\n"
|
|
);
|
|
#endif
|
|
|
|
#endif
|
|
|
|
}
|
|
void nseel_asm_assign_end(void) {}
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_add(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fadd" EEL_F_SUFFIX " (%edi)\n"
|
|
"movl %esi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_add_end(void) {}
|
|
|
|
void nseel_asm_add_op(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fadd" EEL_F_SUFFIX " (%edi)\n"
|
|
"movl %edi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%edi)\n"
|
|
);
|
|
}
|
|
void nseel_asm_add_op_end(void) {}
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_sub(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%edi)\n"
|
|
"fsub" EEL_F_SUFFIX " (%eax)\n"
|
|
"movl %esi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_sub_end(void) {}
|
|
|
|
void nseel_asm_sub_op(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%edi)\n"
|
|
"fsub" EEL_F_SUFFIX " (%eax)\n"
|
|
"movl %edi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%edi)\n"
|
|
);
|
|
}
|
|
void nseel_asm_sub_op_end(void) {}
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_mul(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%edi)\n"
|
|
"fmul" EEL_F_SUFFIX " (%eax)\n"
|
|
"movl %esi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_mul_end(void) {}
|
|
|
|
void nseel_asm_mul_op(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fmul" EEL_F_SUFFIX " (%edi)\n"
|
|
"movl %edi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%edi)\n"
|
|
);
|
|
}
|
|
void nseel_asm_mul_op_end(void) {}
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_div(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%edi)\n"
|
|
"fdiv" EEL_F_SUFFIX " (%eax)\n"
|
|
"movl %esi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_div_end(void) {}
|
|
|
|
void nseel_asm_div_op(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%edi)\n"
|
|
"fdiv" EEL_F_SUFFIX " (%eax)\n"
|
|
"movl %edi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%edi)\n"
|
|
);
|
|
}
|
|
void nseel_asm_div_op_end(void) {}
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_mod(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%edi)\n"
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fabs\n"
|
|
"fistpl (%esi)\n"
|
|
"fabs\n"
|
|
"fistpl 4(%esi)\n"
|
|
"xorl %edx, %edx\n"
|
|
#ifdef TARGET_X64
|
|
"subl %eax, %eax\n"
|
|
#endif
|
|
"cmpl $0, (%esi)\n"
|
|
"je 0f\n" // skip devide, set return to 0
|
|
"movl 4(%esi), %eax\n"
|
|
"divl (%esi)\n"
|
|
"0:\n"
|
|
"movl %edx, (%esi)\n"
|
|
"fildl (%esi)\n"
|
|
"movl %esi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_mod_end(void) {}
|
|
|
|
void nseel_asm_mod_op(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%edi)\n"
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fabs\n"
|
|
"fistpl (%edi)\n"
|
|
"fabs\n"
|
|
"fistpl (%esi)\n"
|
|
#ifdef TARGET_X64
|
|
"subl %eax, %eax\n"
|
|
#endif
|
|
"xorl %edx, %edx\n"
|
|
"cmpl $0, (%edi)\n"
|
|
"je 0f\n" // skip devide, set return to 0
|
|
"movl (%esi), %eax\n"
|
|
"divl (%edi)\n"
|
|
"0:\n"
|
|
"movl %edx, (%edi)\n"
|
|
"fildl (%edi)\n"
|
|
"movl %edi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%edi)\n"
|
|
);
|
|
}
|
|
void nseel_asm_mod_op_end(void) {}
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_or(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%edi)\n"
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"movl %esi, %eax\n"
|
|
"fistpll (%esi)\n"
|
|
"fistpll 8(%esi)\n"
|
|
#ifdef TARGET_X64
|
|
"movll 8(%rsi), %rdi\n"
|
|
"orll %rdi, (%rsi)\n"
|
|
#else
|
|
"movl 8(%esi), %edi\n"
|
|
"movl 12(%esi), %ecx\n"
|
|
"orl %edi, (%esi)\n"
|
|
"orl %ecx, 4(%esi)\n"
|
|
#endif
|
|
"fildll (%esi)\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_or_end(void) {}
|
|
|
|
void nseel_asm_or_op(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%edi)\n"
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fistpll (%edi)\n"
|
|
"fistpll (%esi)\n"
|
|
#ifdef TARGET_X64
|
|
"movll (%rsi), %rax\n"
|
|
"orll %rax, (%rdi)\n"
|
|
#else
|
|
"movl (%esi), %eax\n"
|
|
"movl 4(%esi), %ecx\n"
|
|
"orl %eax, (%edi)\n"
|
|
"orl %ecx, 4(%edi)\n"
|
|
#endif
|
|
"fildll (%edi)\n"
|
|
"movl %edi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%edi)\n"
|
|
);
|
|
}
|
|
void nseel_asm_or_op_end(void) {}
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_and(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%edi)\n"
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"movl %esi, %eax\n"
|
|
"fistpll (%esi)\n"
|
|
"fistpll 8(%esi)\n"
|
|
#ifdef TARGET_X64
|
|
"movll 8(%rsi), %rdi\n"
|
|
"andll %rdi, (%rsi)\n"
|
|
#else
|
|
"movl 8(%esi), %edi\n"
|
|
"movl 12(%esi), %ecx\n"
|
|
"andl %edi, (%esi)\n"
|
|
"andl %ecx, 4(%esi)\n"
|
|
#endif
|
|
"fildll (%esi)\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_and_end(void) {}
|
|
|
|
void nseel_asm_and_op(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%edi)\n"
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fistpll (%edi)\n"
|
|
"fistpll (%esi)\n"
|
|
#ifdef TARGET_X64
|
|
"movll (%rsi), %rax\n"
|
|
"andll %rax, (%rdi)\n"
|
|
#else
|
|
"movl (%esi), %eax\n"
|
|
"movl 4(%esi), %ecx\n"
|
|
"andl %eax, (%edi)\n"
|
|
"andl %ecx, 4(%edi)\n"
|
|
#endif
|
|
"fildll (%edi)\n"
|
|
"movl %edi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%edi)\n"
|
|
);
|
|
}
|
|
void nseel_asm_and_op_end(void) {}
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_uplus(void) // this is the same as doing nothing, it seems
|
|
{
|
|
__asm__(
|
|
""
|
|
);
|
|
}
|
|
void nseel_asm_uplus_end(void) {}
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_uminus(void)
|
|
{
|
|
__asm__(
|
|
#if EEL_F_SIZE == 8
|
|
"movl (%eax), %ecx\n"
|
|
"movl 4(%eax), %edi\n"
|
|
"movl %ecx, (%esi)\n"
|
|
"xorl $0x80000000, %edi\n"
|
|
"movl %esi, %eax\n"
|
|
"movl %edi, 4(%esi)\n"
|
|
"addl $8, %esi\n"
|
|
#else
|
|
"movl (%eax), %ecx\n"
|
|
"xorl $0x80000000, %ecx\n"
|
|
"movl %esi, %eax\n"
|
|
"movl %ecx, (%esi)\n"
|
|
"addl $4, %esi\n"
|
|
#endif
|
|
);
|
|
}
|
|
void nseel_asm_uminus_end(void) {}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_sign(void)
|
|
{
|
|
__asm__(
|
|
|
|
#ifdef TARGET_X64
|
|
|
|
|
|
"movl $0xFFFFFFFF, %rdi\n"
|
|
"movll (%rax), %rcx\n"
|
|
"movll $0x7FFFFFFFFFFFFFFF, %rdx\n"
|
|
"testl %rdx, %rcx\n"
|
|
"jz 1f\n"
|
|
"shr $60, %rcx\n"
|
|
"andl $8, %rcx\n"
|
|
"addll %rdi, %rcx\n"
|
|
"movl %rsi, %rax\n"
|
|
"addl $8, %rsi\n"
|
|
"movll (%rcx), %rdi\n"
|
|
"movll %rdi, (%rax)\n"
|
|
"1:\n"
|
|
|
|
|
|
#else
|
|
|
|
"movl $0xFFFFFFFF, %edi\n"
|
|
#if EEL_F_SIZE == 8
|
|
"movl 4(%eax), %ecx\n"
|
|
"movl (%eax), %edx\n"
|
|
"testl $0xFFFFFFFF, %edx\n"
|
|
"jnz 0f\n"
|
|
#else
|
|
"movl (%eax), %ecx\n"
|
|
#endif
|
|
// high dword (minus sign bit) is zero
|
|
"test $0x7FFFFFFF, %ecx\n"
|
|
"jz 1f\n" // zero zero, return the value passed directly
|
|
"0:\n"
|
|
#if EEL_F_SIZE == 8
|
|
"shrl $28, %ecx\n"
|
|
#else
|
|
"shrl $29, %ecx\n"
|
|
#endif
|
|
|
|
"andl $" EEL_F_SSTR ", %ecx\n"
|
|
"addl %edi, %ecx\n"
|
|
|
|
"movl %esi, %eax\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
|
|
"movl (%ecx), %edi\n"
|
|
#if EEL_F_SIZE == 8
|
|
"movl 4(%ecx), %edx\n"
|
|
#endif
|
|
"movl %edi, (%eax)\n"
|
|
#if EEL_F_SIZE == 8
|
|
"movl %edx, 4(%eax)\n"
|
|
#endif
|
|
"1:\n"
|
|
|
|
#endif
|
|
);
|
|
}
|
|
void nseel_asm_sign_end(void) {}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_bnot(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fabs\n"
|
|
#ifdef TARGET_X64
|
|
"movl $0xFFFFFFFF, %rax\n"
|
|
"fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
|
|
#else
|
|
"fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
|
|
#endif
|
|
"fstsw %ax\n"
|
|
"test $256, %eax\n"
|
|
"movl %esi, %eax\n"
|
|
"jz 0f\n"
|
|
"fld1\n"
|
|
"jmp 1f\n"
|
|
"0:\n"
|
|
"fldz\n"
|
|
"1:\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_bnot_end(void) {}
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_if(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fabs\n"
|
|
#ifdef TARGET_X64
|
|
"movl $0xFFFFFFFF, %rax\n"
|
|
"fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
|
|
"movll $0xFFFFFFFF, %rax\n"
|
|
"movll %rax, (%esi)\n" // conversion script will extend these out to full len
|
|
"movll $0xFFFFFFFF, %rax\n"
|
|
"movll %rax, 8(%esi)\n"
|
|
"fstsw %ax\n"
|
|
"shrl $5, %rax\n"
|
|
"andl $8, %rax\n"
|
|
"movll (%rax, %rsi), %rax\n"
|
|
"subl $8, %rsp\n"
|
|
#else
|
|
"fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
|
|
"movl $0xFFFFFFFF, (%esi)\n"
|
|
"movl $0xFFFFFFFF, 4(%esi)\n"
|
|
"fstsw %ax\n"
|
|
"shrl $6, %eax\n"
|
|
"andl $4, %eax\n"
|
|
"movl (%eax, %esi), %eax\n"
|
|
#endif
|
|
"call *%eax\n"
|
|
#ifdef TARGET_X64
|
|
"addl $8, %rsp\n"
|
|
#endif
|
|
|
|
);
|
|
}
|
|
void nseel_asm_if_end(void) {}
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_repeat(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fistpl (%esi)\n"
|
|
#ifdef TARGET_X64 // safe not sure if movl ecx will zero the high word
|
|
"xorl %ecx, %ecx\n"
|
|
#endif
|
|
"movl (%esi), %ecx\n"
|
|
"cmpl $1, %ecx\n"
|
|
"jl 1f\n"
|
|
"cmpl $" NSEEL_LOOPFUNC_SUPPORT_MAXLEN_STR ", %ecx\n"
|
|
"jl 0f\n"
|
|
"movl $" NSEEL_LOOPFUNC_SUPPORT_MAXLEN_STR ", %ecx\n"
|
|
"0:\n"
|
|
"movl $0xFFFFFFFF, %edx\n"
|
|
"subl $8, %esp\n" /* keep stack aligned -- note this is required on x64 too!*/
|
|
"pushl %esi\n" // revert back to last temp workspace
|
|
"pushl %ecx\n"
|
|
"call *%edx\n"
|
|
"popl %ecx\n"
|
|
"popl %esi\n"
|
|
"addl $8, %esp\n" /* keep stack aligned -- also required on x64*/
|
|
"decl %ecx\n"
|
|
"jnz 0b\n"
|
|
"1:\n"
|
|
);
|
|
}
|
|
void nseel_asm_repeat_end(void) {}
|
|
|
|
void nseel_asm_repeatwhile(void)
|
|
{
|
|
__asm__(
|
|
"movl $" NSEEL_LOOPFUNC_SUPPORT_MAXLEN_STR ", %ecx\n"
|
|
"0:\n"
|
|
"movl $0xFFFFFFFF, %edx\n"
|
|
"subl $8, %esp\n" /* keep stack aligned -- required on x86 and x64*/
|
|
"pushl %esi\n" // revert back to last temp workspace
|
|
"pushl %ecx\n"
|
|
"call *%edx\n"
|
|
"popl %ecx\n"
|
|
"popl %esi\n"
|
|
"addl $8, %esp\n" /* keep stack aligned -- required on x86 and x64 */
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fabs\n"
|
|
#ifdef TARGET_X64
|
|
"movl $0xFFFFFFFF, %rax\n"
|
|
"fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
|
|
#else
|
|
"fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
|
|
#endif
|
|
"fstsw %ax\n"
|
|
"testl $256, %eax\n"
|
|
"jnz 0f\n"
|
|
"decl %ecx\n"
|
|
"jnz 0b\n"
|
|
"0:\n"
|
|
"movl %esi, %eax\n"
|
|
);
|
|
}
|
|
void nseel_asm_repeatwhile_end(void) {}
|
|
|
|
|
|
void nseel_asm_band(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fabs\n"
|
|
#ifdef TARGET_X64
|
|
"movl $0xFFFFFFFF, %rax\n"
|
|
"fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
|
|
#else
|
|
"fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
|
|
#endif
|
|
"fstsw %ax\n"
|
|
"testl $256, %eax\n"
|
|
"jnz 0f\n" // if Z, then we are nonzero
|
|
|
|
"movl $0xFFFFFFFF, %ecx\n"
|
|
#ifdef TARGET_X64
|
|
"subl $8, %rsp\n"
|
|
#endif
|
|
"call *%ecx\n"
|
|
#ifdef TARGET_X64
|
|
"addl $8, %rsp\n"
|
|
#endif
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fabs\n"
|
|
#ifdef TARGET_X64
|
|
"movl $0xFFFFFFFF, %rax\n"
|
|
"fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
|
|
#else
|
|
"fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
|
|
#endif
|
|
"fstsw %ax\n"
|
|
"testl $256, %eax\n"
|
|
"jnz 0f\n"
|
|
"fld1\n"
|
|
"jmp 1f\n"
|
|
|
|
"0:\n"
|
|
"fldz\n"
|
|
"1:\n"
|
|
|
|
"movl %esi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_band_end(void) {}
|
|
|
|
void nseel_asm_bor(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fabs\n"
|
|
#ifdef TARGET_X64
|
|
"movl $0xFFFFFFFF, %rax\n"
|
|
"fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
|
|
#else
|
|
"fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
|
|
#endif
|
|
"fstsw %ax\n"
|
|
"testl $256, %eax\n"
|
|
"jz 0f\n" // if Z, then we are nonzero
|
|
|
|
"movl $0xFFFFFFFF, %ecx\n"
|
|
#ifdef TARGET_X64
|
|
"subl $8, %rsp\n"
|
|
#endif
|
|
"call *%ecx\n"
|
|
#ifdef TARGET_X64
|
|
"addl $8, %rsp\n"
|
|
#endif
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fabs\n"
|
|
#ifdef TARGET_X64
|
|
"movl $0xFFFFFFFF, %rax\n"
|
|
"fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
|
|
#else
|
|
"fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
|
|
#endif
|
|
"fstsw %ax\n"
|
|
"testl $256, %eax\n"
|
|
"jz 0f\n"
|
|
"fldz\n"
|
|
"jmp 1f\n"
|
|
|
|
"0:\n"
|
|
"fld1\n"
|
|
"1:\n"
|
|
|
|
"movl %esi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_bor_end(void) {}
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_equal(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fsub" EEL_F_SUFFIX " (%edi)\n"
|
|
"fabs\n"
|
|
#ifdef TARGET_X64
|
|
"movl $0xFFFFFFFF, %rax\n"
|
|
"fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
|
|
#else
|
|
"fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
|
|
#endif
|
|
"fstsw %ax\n"
|
|
"testl $256, %eax\n"
|
|
"movl %esi, %eax\n"
|
|
"jz 0f\n"
|
|
"fld1\n"
|
|
"jmp 1f\n"
|
|
"0:\n"
|
|
"fldz\n"
|
|
"1:\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_equal_end(void) {}
|
|
//
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_notequal(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fsub" EEL_F_SUFFIX " (%edi)\n"
|
|
"fabs\n"
|
|
#ifdef TARGET_X64
|
|
"movl $0xFFFFFFFF, %rax\n"
|
|
"fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
|
|
#else
|
|
"fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
|
|
#endif
|
|
"fstsw %ax\n"
|
|
"testl $256, %eax\n"
|
|
"movl %esi, %eax\n"
|
|
"jnz 0f\n"
|
|
"fld1\n"
|
|
"jmp 1f\n"
|
|
"0:\n"
|
|
"fldz\n"
|
|
"1:\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_notequal_end(void) {}
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_below(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%edi)\n"
|
|
"fcomp" EEL_F_SUFFIX " (%eax)\n"
|
|
"fstsw %ax\n"
|
|
"testl $256, %eax\n"
|
|
"movl %esi, %eax\n"
|
|
"jz 0f\n"
|
|
"fld1\n"
|
|
"jmp 1f\n"
|
|
"0:\n"
|
|
"fldz\n"
|
|
"1:\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_below_end(void) {}
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_beloweq(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fcomp" EEL_F_SUFFIX " (%edi)\n"
|
|
"fstsw %ax\n"
|
|
"testl $256, %eax\n"
|
|
"movl %esi, %eax\n"
|
|
"jnz 0f\n"
|
|
"fld1\n"
|
|
"jmp 1f\n"
|
|
"0:\n"
|
|
"fldz\n"
|
|
"1:\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_beloweq_end(void) {}
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------
|
|
void nseel_asm_above(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fcomp" EEL_F_SUFFIX " (%edi)\n"
|
|
"fstsw %ax\n"
|
|
"testl $256, %eax\n"
|
|
"movl %esi, %eax\n"
|
|
"jz 0f\n"
|
|
"fld1\n"
|
|
"jmp 1f\n"
|
|
"0:\n"
|
|
"fldz\n"
|
|
"1:\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_above_end(void) {}
|
|
|
|
void nseel_asm_aboveeq(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%edi)\n"
|
|
"fcomp" EEL_F_SUFFIX " (%eax)\n"
|
|
"fstsw %ax\n"
|
|
"testl $256, %eax\n"
|
|
"movl %esi, %eax\n"
|
|
"jnz 0f\n"
|
|
"fld1\n"
|
|
"jmp 1f\n"
|
|
"0:\n"
|
|
"fldz\n"
|
|
"1:\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
);
|
|
}
|
|
void nseel_asm_aboveeq_end(void) {}
|
|
|
|
|
|
|
|
void nseel_asm_min(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%edi)\n"
|
|
"fcomp" EEL_F_SUFFIX " (%eax)\n"
|
|
"pushl %eax\n"
|
|
"fstsw %ax\n"
|
|
"testl $256, %eax\n"
|
|
"popl %eax\n"
|
|
"jz 0f\n"
|
|
"movl %edi, %eax\n"
|
|
"0:\n"
|
|
);
|
|
|
|
}
|
|
void nseel_asm_min_end(void) {}
|
|
|
|
void nseel_asm_max(void)
|
|
{
|
|
__asm__(
|
|
"fld" EEL_F_SUFFIX " (%edi)\n"
|
|
"fcomp" EEL_F_SUFFIX " (%eax)\n"
|
|
"pushl %eax\n"
|
|
"fstsw %ax\n"
|
|
"testl $256, %eax\n"
|
|
"popl %eax\n"
|
|
"jnz 0f\n"
|
|
"movl %edi, %eax\n"
|
|
"0:\n"
|
|
);
|
|
}
|
|
void nseel_asm_max_end(void) {}
|
|
|
|
|
|
|
|
|
|
|
|
// just generic functions left, yay
|
|
|
|
|
|
|
|
|
|
void _asm_generic3parm(void)
|
|
{
|
|
__asm__(
|
|
#ifdef TARGET_X64
|
|
|
|
#ifdef AMD64ABI
|
|
|
|
"movl %rsi, %r15\n"
|
|
"movl %rdi, %rdx\n" // third parameter = parm
|
|
"movl $0xFFFFFFFF, %rdi\n" // first parameter= context
|
|
|
|
"movl %ecx, %rsi\n" // second parameter = parm
|
|
"movl %rax, %rcx\n" // fourth parameter = parm
|
|
"movl $0xffffffff, %rax\n" // call function
|
|
"subl $128, %rsp\n"
|
|
"call *%rax\n"
|
|
|
|
"movl %r15, %rsi\n"
|
|
"addl $128, %rsp\n"
|
|
|
|
#else
|
|
"movl %ecx, %edx\n" // second parameter = parm
|
|
"movl $0xFFFFFFFF, %ecx\n" // first parameter= context
|
|
"movl %rdi, %r8\n" // third parameter = parm
|
|
"movl %rax, %r9\n" // fourth parameter = parm
|
|
"movl $0xffffffff, %edi\n" // call function
|
|
"subl $128, %rsp\n"
|
|
"call *%edi\n"
|
|
"addl $128, %rsp\n"
|
|
#endif
|
|
|
|
#else
|
|
SAVE_STACK
|
|
"movl $0xFFFFFFFF, %edx\n"
|
|
"pushl %eax\n" // push parameter
|
|
"pushl %edi\n" // push parameter
|
|
"pushl %ecx\n" // push parameter
|
|
"pushl %edx\n" // push context pointer
|
|
"movl $0xffffffff, %edi\n"
|
|
"call *%edi\n"
|
|
"addl $16, %esp\n"
|
|
RESTORE_STACK
|
|
#endif
|
|
);
|
|
}
|
|
void _asm_generic3parm_end(void) {}
|
|
|
|
|
|
void _asm_generic3parm_retd(void)
|
|
{
|
|
__asm__(
|
|
#ifdef TARGET_X64
|
|
#ifdef AMD64ABI
|
|
"movl %rsi, %r15\n"
|
|
"movl %rdi, %rdx\n" // third parameter = parm
|
|
"movl $0xFFFFFFFF, %rdi\n" // first parameter= context
|
|
"movl %ecx, %rsi\n" // second parameter = parm
|
|
"movl %rax, %rcx\n" // fourth parameter = parm
|
|
"movl $0xffffffff, %rax\n" // call function
|
|
"subl $128, %rsp\n"
|
|
"call *%rax\n"
|
|
"addl $128, %rsp\n"
|
|
"movl %r15, %rsi\n"
|
|
"movl %r15, %rax\n"
|
|
"movq xmm0, (%r15)\n"
|
|
"addl $8, %rsi\n"
|
|
#else
|
|
"movl %ecx, %edx\n" // second parameter = parm
|
|
"movl $0xFFFFFFFF, %ecx\n" // first parameter= context
|
|
"movl %rdi, %r8\n" // third parameter = parm
|
|
"movl %rax, %r9\n" // fourth parameter = parm
|
|
"movl $0xffffffff, %edi\n" // call function
|
|
"subl $128, %rsp\n"
|
|
"call *%edi\n"
|
|
"addl $128, %rsp\n"
|
|
"movq xmm0, (%rsi)\n"
|
|
"movl %rsi, %rax\n"
|
|
"addl $8, %rsi\n"
|
|
#endif
|
|
#else
|
|
SAVE_STACK
|
|
"movl $0xFFFFFFFF, %edx\n"
|
|
"pushl %eax\n" // push parameter
|
|
"pushl %edi\n" // push parameter
|
|
"pushl %ecx\n" // push parameter
|
|
"pushl %edx\n" // push context pointer
|
|
"movl $0xffffffff, %edi\n"
|
|
"call *%edi\n"
|
|
"movl %esi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
"addl $16, %esp\n"
|
|
RESTORE_STACK
|
|
#endif
|
|
);
|
|
}
|
|
void _asm_generic3parm_retd_end(void) {}
|
|
|
|
|
|
void _asm_generic2parm(void) // this prob neds to be fixed for ppc
|
|
{
|
|
__asm__(
|
|
#ifdef TARGET_X64
|
|
|
|
#ifdef AMD64ABI
|
|
"movl %rsi, %r15\n"
|
|
"movl %edi, %esi\n" // second parameter = parm
|
|
"movl $0xFFFFFFFF, %edi\n" // first parameter= context
|
|
"movl %rax, %rdx\n" // third parameter = parm
|
|
"movl $0xffffffff, %rcx\n" // call function
|
|
"subl $128, %rsp\n"
|
|
"call *%rcx\n"
|
|
"movl %r15, %rsi\n"
|
|
"addl $128, %rsp\n"
|
|
#else
|
|
"movl $0xFFFFFFFF, %ecx\n" // first parameter= context
|
|
"movl %edi, %edx\n" // second parameter = parm
|
|
"movl %rax, %r8\n" // third parameter = parm
|
|
"movl $0xffffffff, %edi\n" // call function
|
|
"subl $128, %rsp\n"
|
|
"call *%edi\n"
|
|
"addl $128, %rsp\n"
|
|
#endif
|
|
#else
|
|
SAVE_STACK
|
|
"movl $0xFFFFFFFF, %edx\n"
|
|
"subl $4, %esp\n" // keep stack aligned
|
|
"pushl %eax\n" // push parameter
|
|
"pushl %edi\n" // push parameter
|
|
"pushl %edx\n" // push context pointer
|
|
"movl $0xffffffff, %edi\n"
|
|
"call *%edi\n"
|
|
"addl $16, %esp\n"
|
|
RESTORE_STACK
|
|
#endif
|
|
);
|
|
}
|
|
void _asm_generic2parm_end(void) {}
|
|
|
|
|
|
void _asm_generic2parm_retd(void)
|
|
{
|
|
__asm__(
|
|
#ifdef TARGET_X64
|
|
#ifdef AMD64ABI
|
|
"movl %rsi, %r15\n"
|
|
"movl %rdi, %rsi\n" // second parameter = parm
|
|
"movl $0xFFFFFFFF, %rdi\n" // first parameter= context
|
|
"movl %rax, %rdx\n" // third parameter = parm
|
|
"movl $0xffffffff, %rcx\n" // call function
|
|
"subl $128, %rsp\n"
|
|
"call *%rcx\n"
|
|
"movl %r15, %rsi\n"
|
|
"addl $128, %rsp\n"
|
|
"movq xmm0, (%r15)\n"
|
|
"movl %r15, %rax\n"
|
|
"addl $8, %rsi\n"
|
|
#else
|
|
"movl $0xFFFFFFFF, %ecx\n" // first parameter= context
|
|
"movl %edi, %edx\n" // second parameter = parm
|
|
"movl %rax, %r8\n" // third parameter = parm
|
|
"movl $0xffffffff, %edi\n" // call function
|
|
"subl $128, %rsp\n"
|
|
"call *%edi\n"
|
|
"addl $128, %rsp\n"
|
|
"movq xmm0, (%rsi)\n"
|
|
"movl %rsi, %rax\n"
|
|
"addl $8, %rsi\n"
|
|
#endif
|
|
#else
|
|
SAVE_STACK
|
|
"movl $0xFFFFFFFF, %edx\n"
|
|
"pushl %eax\n" // push parameter
|
|
"pushl %edi\n" // push parameter
|
|
"pushl %ecx\n" // push parameter
|
|
"pushl %edx\n" // push context pointer
|
|
"movl $0xffffffff, %edi\n"
|
|
"call *%edi\n"
|
|
"movl %esi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
"addl $16, %esp\n"
|
|
RESTORE_STACK
|
|
#endif
|
|
);
|
|
}
|
|
void _asm_generic2parm_retd_end(void) {}
|
|
|
|
|
|
|
|
|
|
|
|
void _asm_generic1parm(void) // this prob neds to be fixed for ppc
|
|
{
|
|
__asm__(
|
|
#ifdef TARGET_X64
|
|
#ifdef AMD64ABI
|
|
"movl $0xFFFFFFFF, %rdi\n" // first parameter= context
|
|
"movl %rsi, %r15\n"
|
|
"movl %eax, %rsi\n" // second parameter = parm
|
|
"subl $128, %rsp\n"
|
|
"movl $0xffffffff, %rcx\n" // call function
|
|
"call *%rcx\n"
|
|
"movl %r15, %rsi\n"
|
|
"addl $128, %rsp\n"
|
|
#else
|
|
"movl $0xFFFFFFFF, %ecx\n" // first parameter= context
|
|
"movl %eax, %edx\n" // second parameter = parm
|
|
"movl $0xffffffff, %edi\n" // call function
|
|
"subl $128, %rsp\n"
|
|
"call *%edi\n"
|
|
"addl $128, %rsp\n"
|
|
#endif
|
|
#else
|
|
SAVE_STACK
|
|
"movl $0xFFFFFFFF, %edx\n"
|
|
"subl $8, %esp\n" // keep stack aligned
|
|
"pushl %eax\n" // push parameter
|
|
"pushl %edx\n" // push context pointer
|
|
"movl $0xffffffff, %edi\n"
|
|
"call *%edi\n"
|
|
"addl $16, %esp\n"
|
|
RESTORE_STACK
|
|
#endif
|
|
|
|
);
|
|
}
|
|
void _asm_generic1parm_end(void) {}
|
|
|
|
|
|
void _asm_generic1parm_retd(void) // 1 parameter returning double
|
|
{
|
|
__asm__(
|
|
#ifdef TARGET_X64
|
|
#ifdef AMD64ABI
|
|
"movl %rsi, %r15\n"
|
|
"movl $0xFFFFFFFF, %rdi\n" // first parameter= context
|
|
"movl %rax, %rsi\n" // second parameter = parm
|
|
"movl $0xffffffff, %rcx\n" // call function
|
|
"subl $128, %rsp\n"
|
|
"call *%rcx\n"
|
|
"movl %r15, %rsi\n"
|
|
"addl $128, %rsp\n"
|
|
"movq xmm0, (%r15)\n"
|
|
"movl %r15, %rax\n"
|
|
"addl $8, %rsi\n"
|
|
#else
|
|
"movl $0xFFFFFFFF, %ecx\n" // first parameter= context
|
|
"movl %eax, %edx\n" // second parameter = parm
|
|
"movl $0xffffffff, %edi\n" // call function
|
|
"subl $128, %rsp\n"
|
|
"call *%edi\n"
|
|
"addl $128, %rsp\n"
|
|
"movq xmm0, (%rsi)\n"
|
|
"movl %rsi, %rax\n"
|
|
"addl $8, %rsi\n"
|
|
#endif
|
|
#else
|
|
SAVE_STACK
|
|
"movl $0xFFFFFFFF, %edx\n"
|
|
"subl $8, %esp\n" // keep stack aligned
|
|
"pushl %eax\n" // push parameter
|
|
"pushl %edx\n" // push context pointer
|
|
"movl $0xffffffff, %edi\n"
|
|
"call *%edi\n"
|
|
"movl %esi, %eax\n"
|
|
"fstp" EEL_F_SUFFIX " (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
"addl $16, %esp\n"
|
|
RESTORE_STACK
|
|
#endif
|
|
);
|
|
}
|
|
void _asm_generic1parm_retd_end(void) {}
|
|
|
|
|
|
|
|
|
|
|
|
// this gets its own stub because it's pretty crucial for performance :/
|
|
|
|
void _asm_megabuf(void)
|
|
{
|
|
__asm__(
|
|
SAVE_STACK
|
|
|
|
#ifdef TARGET_X64
|
|
|
|
|
|
#ifdef AMD64ABI
|
|
|
|
"movl %rsi, %r15\n"
|
|
"movl $0xFFFFFFFF, %rdi\n" // first parameter = context pointer
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"movl $0xFFFFFFFF, %rdx\n"
|
|
"fadd" EEL_F_SUFFIX " (%rdx)\n"
|
|
"fistpl (%r15)\n"
|
|
"xorl %rsi, %rsi\n"
|
|
"movl (%r15), %esi\n" // r15 = esi (from above)
|
|
"movl $0xffffffff, %edx\n"
|
|
"subl $128, %rsp\n"
|
|
"call *%edx\n"
|
|
"movl %r15, %rsi\n"
|
|
"addl $128, %rsp\n"
|
|
"and %rax, %rax\n"
|
|
"jnz 0f\n"
|
|
"movl %r15, %rax\n"
|
|
"movll $0, (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %rsi\n"
|
|
"0:"
|
|
|
|
#else
|
|
"movl $0xFFFFFFFF, %ecx\n" // first parameter = context pointer
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"movl $0xFFFFFFFF, %edx\n"
|
|
"fadd" EEL_F_SUFFIX " (%rdx)\n"
|
|
"fistpl (%esi)\n"
|
|
"xorl %rdx, %rdx\n"
|
|
"movl (%esi), %edx\n"
|
|
"movl $0xffffffff, %edi\n"
|
|
"subl $128, %rsp\n"
|
|
"call *%edi\n"
|
|
"addl $128, %rsp\n"
|
|
"and %rax, %rax\n"
|
|
"jnz 0f\n"
|
|
"movl %rsi, %rax\n"
|
|
"movll $0, (%esi)\n"
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
"0:"
|
|
#endif
|
|
|
|
|
|
#else
|
|
"movl $0xFFFFFFFF, %edx\n"
|
|
"fld" EEL_F_SUFFIX " (%eax)\n"
|
|
"fadd" EEL_F_SUFFIX " (0xFFFFFFFF)\n"
|
|
"fistpl (%esi)\n"
|
|
"subl $8, %esp\n" // keep stack aligned
|
|
"pushl (%esi)\n" // parameter
|
|
"pushl %edx\n" // push context pointer
|
|
"movl $0xffffffff, %edi\n"
|
|
"call *%edi\n"
|
|
"addl $16, %esp\n"
|
|
"and %eax, %eax\n"
|
|
"jnz 0f\n"
|
|
"movl %esi, %eax\n"
|
|
"movl $0, (%esi)\n"
|
|
#if EEL_F_SIZE == 8
|
|
"movl $0, 4(%esi)\n"
|
|
#endif
|
|
"addl $" EEL_F_SSTR ", %esi\n"
|
|
"0:"
|
|
|
|
|
|
#endif
|
|
|
|
RESTORE_STACK
|
|
|
|
);
|
|
}
|
|
|
|
void _asm_megabuf_end(void) {}
|
|
|
|
|
|
#ifdef TARGET_X64
|
|
void win64_callcode()
|
|
{
|
|
__asm__(
|
|
#ifdef AMD64ABI
|
|
"movll %edi, %eax\n"
|
|
#else
|
|
"movll %ecx, %eax\n"
|
|
#endif
|
|
|
|
"push %rbx\n"
|
|
"push %rbp\n"
|
|
#ifndef AMD64ABI
|
|
"push %rdi\n"
|
|
"push %rsi\n"
|
|
"push %r12\n"
|
|
"push %r13\n"
|
|
#endif
|
|
"push %r14\n" // on AMD64ABI, we'll use r14/r15 to save edi/esi
|
|
"push %r15\n"
|
|
"call %eax\n"
|
|
"pop %r15\n"
|
|
"pop %r14\n"
|
|
#ifndef AMD64ABI
|
|
"pop %r13\n"
|
|
"pop %r12\n"
|
|
"pop %rsi\n"
|
|
"pop %rdi\n"
|
|
"fclex\n"
|
|
#endif
|
|
"pop %rbp\n"
|
|
"pop %rbx\n"
|
|
"ret\n"
|
|
);
|
|
}
|
|
|
|
#endif |