Re: _vcomp_fork stack frame puzzle

2012-08-12 Thread Dan Kegel
Using varargs like Andre tried doesn't work because pushing a va_list
isn't the same as pushing a list of arguments.
So I think we need assembly.  The assembly I gave earlier is wrong
because it cleans up the stack, which it's not allowed to do.
I've attached an updated patch to
http://bugs.winehq.org/show_bug.cgi?id=26688
with a _vcomp_fork that works for simple loops with and without
bound variables.

I guess the next step is porting the serial stub for _vcomp_fork to 64 bits.




Re: _vcomp_fork stack frame puzzle

2012-08-10 Thread Dan Kegel
On Fri, Aug 10, 2012 at 7:37 PM, Dan Kegel  wrote:
> Yes indeed, this works:
>
> extern void WINAPIV VCOMP__vcomp_fork(DWORD parallel, int ncount, void
> (__cdecl *helper)(__ms_va_list), ...);
> __ASM_GLOBAL_FUNC( VCOMP__vcomp_fork,
>"pop %eax\n\t"   /* save return address */
>"add $8,%esp\n\t"/* skip parallel and ncount */
>"pop %ebx\n\t"   /* save helper */
>"push %eax\n\t"  /* set up return address */
>"jmp %ebx"   /* enter handler */
>  )

(Or maybe %edx instead of %ebx;
http://en.wikipedia.org/wiki/X86_calling_conventions
suggests %ebx shouldn't be modified by the callee.)




Re: _vcomp_fork stack frame puzzle

2012-08-10 Thread Dan Kegel
Yes indeed, this works:

extern void WINAPIV VCOMP__vcomp_fork(DWORD parallel, int ncount, void
(__cdecl *helper)(__ms_va_list), ...);
__ASM_GLOBAL_FUNC( VCOMP__vcomp_fork,
   "pop %eax\n\t"   /* save return address */
   "add $8,%esp\n\t"/* skip parallel and ncount */
   "pop %ebx\n\t"   /* save helper */
   "push %eax\n\t"  /* set up return address */
   "jmp %ebx"   /* enter handler */
 )




Re: _vcomp_fork stack frame puzzle

2012-08-10 Thread Dan Kegel
Yeah, it might be as simple as
_vcomp_vfork  proc
  add sp,4   ; skip parallel flag and arg count
  ret   ; jump to helper function, leaving its args on stack

or something like that.




Re: _vcomp_fork stack frame puzzle

2012-08-09 Thread André Hentschel
Am 09.08.2012 07:49, schrieb Dan Kegel:
> It seems like Andre's varargs code should be right,
> but something's not connecting.  I even tried beer,
> and it still didn't work.

:D
maybe you should try to write it in assembler and later try to move things to 
C...


-- 

Best Regards, André Hentschel




_vcomp_fork stack frame puzzle

2012-08-08 Thread Dan Kegel
Having fun trying to figure out what's in the black box of _vcomp_fork(),
the helper function that spawns threads in Visual C's OpenMP
support library.

The C source code

#include 
#include 
int main(int argc, char **argv)
{
double d;
double e;
int i;
printf("&d is %p, &e is %p\n", &d, &e);
#pragma omp parallel for
for (i=0; i<3; i++) {
printf("&d is %p\n", &d);
}
#pragma omp parallel for
for (i=0; i<3; i++) {
printf("&d is %p, &e is %p\n", &d, &e);
}
return 0;
}

when compiled with
  cl /MD /openmp /FAs odd.c

generates an .exe and a mixed assembly / source .asm listing.
The compiler puts the loop into a helper function, and invokes
the helper using _vcomp_fork(), which is called with
a flag saying whether to parallelize,
a pointer to the helper function, a count,
and then a pointer to each variable referenced
by the loop from the outer scope.
The code in the helper function knows to
get the addresses of the variables from the stack.

When run with native vcomp.dll, this prints out
the right addresses inside the loop.
When run with my slightly less stubby builtin vcomp patch attached to
http://bugs.winehq.org/show_bug.cgi?id=26688
(based on Andre's earlier patch),
it prints out garbage.

It seems like Andre's varargs code should be right,
but something's not connecting.  I even tried beer,
and it still didn't work.

I guess I should fire up a debugger and see what's going
on, but I don't want to accidentally see too much about
what native's doing.

Suggestions, anyone?
- Dan