winamp/Src/Plugins/Visualization/vis_milk2/ns-eel2/asm-nseel-x86-gcc.c
2024-09-24 14:54:57 +02:00

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