[PATCH] ntdll: Implement _alldvrm() and _aulldvrm().

Alexandre Julliard julliard at winehq.org
Tue Apr 3 05:51:51 CDT 2018


Zebediah Figura <z.figura12 at gmail.com> writes:

> +static LONGLONG _alldvrm_wrapper(LARGE_INTEGER a, LARGE_INTEGER b, LARGE_INTEGER *rem)
> +{
> +    /* _alldvrm() divides two LONGLONGs and returns the quotient in edx:eax and
> +     * the remainder in ebx:ecx. */
> +
> +    LONGLONG ret;
> +
> +    __asm__ __volatile__ (
> +        "pushl %%ebx\n\t"
> +        "pushl %3\n\t"
> +        "pushl %4\n\t"
> +        "pushl %5\n\t"
> +        "pushl %6\n\t"
> +        "call *%7\n\t"
> +        "movl %%ebx, %1\n\t"
> +        "movl %%ecx, %2\n\t"
> +        "popl %%ebx\n\t"
> +        : "=A" (ret), "=r" (rem->HighPart), "=r" (rem->LowPart)
> +        : "ri" (b.HighPart), "ri" (b.LowPart), "ri" (a.HighPart), "ri" (a.LowPart), "m" (p_alldvrm)
> +        : "ebx", "ecx"
> +    );

That sort of assembly with a million register constraints is fragile,
and will most likely break depending on optimization options.

> +    /* _alldvrm(0x0123456701234567, 3) */
> +    a.HighPart = a.LowPart = 0x01234567;
> +    b.QuadPart = 3;
> +    ret = _alldvrm_wrapper(a, b, &rem);
> +    ok(ret == 0x61172255b66c77ULL, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);

Please avoid long long constants.

-- 
Alexandre Julliard
julliard at winehq.org



More information about the wine-devel mailing list