--- libcoro/coro.c 2008/04/24 12:40:38 1.31 +++ libcoro/coro.c 2008/11/05 01:54:34 1.36 @@ -122,43 +122,44 @@ #endif #if CORO_ASM -void __attribute__((__noinline__, __fastcall__)) -coro_transfer (struct coro_context *prev, struct coro_context *next) -{ - asm volatile ( +asm ( + ".text\n" + ".globl coro_transfer\n" + ".type coro_transfer, @function\n" + "coro_transfer:\n" #if __amd64 -# define NUM_CLOBBERED 5 - "push %%rbx\n\t" - "push %%r12\n\t" - "push %%r13\n\t" - "push %%r14\n\t" - "push %%r15\n\t" - "mov %%rsp, %0\n\t" - "mov %1, %%rsp\n\t" - "pop %%r15\n\t" - "pop %%r14\n\t" - "pop %%r13\n\t" - "pop %%r12\n\t" - "pop %%rbx\n\t" +# define NUM_ALIGN 1 +# define NUM_SAVED 5 + "\tpush %rbx\n" + "\tpush %r12\n" + "\tpush %r13\n" + "\tpush %r14\n" + "\tpush %r15\n" + "\tmov %rsp, (%rdi)\n" + "\tmov (%rsi), %rsp\n" + "\tpop %r15\n" + "\tpop %r14\n" + "\tpop %r13\n" + "\tpop %r12\n" + "\tpop %rbx\n" #elif __i386 -# define NUM_CLOBBERED 4 - "push %%ebx\n\t" - "push %%esi\n\t" - "push %%edi\n\t" - "push %%ebp\n\t" - "mov %%esp, %0\n\t" - "mov %1, %%esp\n\t" - "pop %%ebp\n\t" - "pop %%edi\n\t" - "pop %%esi\n\t" - "pop %%ebx\n\t" +# define NUM_ALIGN 1 +# define NUM_SAVED 4 + "\tpush %ebx\n" + "\tpush %esi\n" + "\tpush %edi\n" + "\tpush %ebp\n" + "\tmov %esp, (%eax)\n" + "\tmov (%edx), %esp\n" + "\tpop %ebp\n" + "\tpop %edi\n" + "\tpop %esi\n" + "\tpop %ebx\n" #else # error unsupported architecture #endif - : "=m" (prev->sp) - : "m" (next->sp) - ); -} + "\tret\n" +); #endif #if CORO_PTHREAD @@ -187,6 +188,8 @@ return 0; } +asm(""); + void coro_transfer(coro_context *prev, coro_context *next) { pthread_cond_init (&prev->c, 0); @@ -208,7 +211,7 @@ ctx->uc.uc_link = 0; ctx->uc.uc_stack.ss_sp = STACK_ADJUST_PTR (sptr,ssize); - ctx->uc.uc_stack.ss_size = (size_t) STACK_ADJUST_SIZE (sptr,ssize); + ctx->uc.uc_stack.ss_size = (size_t)STACK_ADJUST_SIZE (sptr,ssize); ctx->uc.uc_stack.ss_flags = 0; makecontext (&(ctx->uc), (void (*)()) coro, 1, arg); @@ -283,17 +286,17 @@ setjmp (ctx->env); #if __CYGWIN__ - ctx->env[7] = (long)((char *)sptr + ssize); + ctx->env[7] = (long)((char *)sptr + ssize) - sizeof (long); ctx->env[8] = (long)coro_init; #elif defined(_M_IX86) ((_JUMP_BUFFER *)&ctx->env)->Eip = (long)coro_init; - ((_JUMP_BUFFER *)&ctx->env)->Esp = (long)STACK_ADJUST_PTR (sptr, ssize); + ((_JUMP_BUFFER *)&ctx->env)->Esp = (long)STACK_ADJUST_PTR (sptr, ssize) - sizeof (long); #elif defined(_M_AMD64) ((_JUMP_BUFFER *)&ctx->env)->Rip = (__int64)coro_init; - ((_JUMP_BUFFER *)&ctx->env)->Rsp = (__int64)STACK_ADJUST_PTR (sptr, ssize); + ((_JUMP_BUFFER *)&ctx->env)->Rsp = (__int64)STACK_ADJUST_PTR (sptr, ssize) - sizeof (long); #elif defined(_M_IA64) ((_JUMP_BUFFER *)&ctx->env)->StIIP = (__int64)coro_init; - ((_JUMP_BUFFER *)&ctx->env)->IntSp = (__int64)STACK_ADJUST_PTR (sptr, ssize); + ((_JUMP_BUFFER *)&ctx->env)->IntSp = (__int64)STACK_ADJUST_PTR (sptr, ssize) - sizeof (long); #else # error "microsoft libc or architecture not supported" #endif @@ -303,16 +306,16 @@ _setjmp (ctx->env); #if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 0 && defined (JB_PC) && defined (JB_SP) ctx->env[0].__jmpbuf[JB_PC] = (long)coro_init; - ctx->env[0].__jmpbuf[JB_SP] = (long)STACK_ADJUST_PTR (sptr, ssize); + ctx->env[0].__jmpbuf[JB_SP] = (long)STACK_ADJUST_PTR (sptr, ssize) - sizeof (long); #elif __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 0 && defined (__mc68000__) ctx->env[0].__jmpbuf[0].__aregs[0] = (long int)coro_init; - ctx->env[0].__jmpbuf[0].__sp = (int *)((char *)sptr + ssize); + ctx->env[0].__jmpbuf[0].__sp = (int *)((char *)sptr + ssize) - sizeof (long); #elif defined (__GNU_LIBRARY__) && defined (__i386__) ctx->env[0].__jmpbuf[0].__pc = (char *)coro_init; - ctx->env[0].__jmpbuf[0].__sp = (void *)((char *)sptr + ssize); + ctx->env[0].__jmpbuf[0].__sp = (void *)((char *)sptr + ssize) - sizeof (long); #elif defined (__GNU_LIBRARY__) && defined (__amd64__) ctx->env[0].__jmpbuf[JB_PC] = (long)coro_init; - ctx->env[0].__jmpbuf[JB_RSP] = (long)STACK_ADJUST_PTR (sptr, ssize); + ctx->env[0].__jmpbuf[0].__sp = (void *)((char *)sptr + ssize) - sizeof (long); #else # error "linux libc or architecture not supported" #endif @@ -321,14 +324,14 @@ setjmp (ctx->env); ctx->env[JB_PC] = (__uint64_t)coro_init; - ctx->env[JB_SP] = (__uint64_t)STACK_ADJUST_PTR (sptr, ssize); + ctx->env[JB_SP] = (__uint64_t)STACK_ADJUST_PTR (sptr, ssize) - sizeof (long); # elif CORO_ASM ctx->sp = (volatile void **)(ssize + (char *)sptr); + ctx->sp -= NUM_ALIGN; *--ctx->sp = (void *)coro_init; - *--ctx->sp = (void *)coro_init; // this is needed when the prologue saves ebp - ctx->sp -= NUM_CLOBBERED; + ctx->sp -= NUM_SAVED; # endif