Module: wine Branch: master Commit: fffed9b3b198b9f26157e903291af0ee6de33867 URL: https://gitlab.winehq.org/wine/wine/-/commit/fffed9b3b198b9f26157e903291af0e...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Apr 24 16:54:48 2024 +0200
oleaut32: Extend 8- and 16-bit parameters on ARM.
And update tests to show that Windows does the same.
---
dlls/oleaut32/tests/typelib.c | 31 +++++++++++++++-------------- dlls/oleaut32/typelib.c | 46 +++++++++++++++++++++---------------------- 2 files changed, 39 insertions(+), 38 deletions(-)
diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c index d755729d9e9..f8606bcfe68 100644 --- a/dlls/oleaut32/tests/typelib.c +++ b/dlls/oleaut32/tests/typelib.c @@ -1188,7 +1188,11 @@ static int WINAPI int_func( int a0, int a1, int a2, int a3, int a4 ) { ok( a0 == 1, "wrong arg0 %x\n", a0 ); ok( a1 == -1, "wrong arg1 %x\n", a1 ); +#ifdef __arm__ /* parameters are extended on arm */ + ok( a2 == 1234, "wrong arg2 %x\n", a2 ); +#else ok( a2 == (0x55550000 | 1234), "wrong arg2 %x\n", a2 ); +#endif ok( a3 == 0xdeadbeef, "wrong arg3 %x\n", a3 ); ok( a4 == 0x555555fd, "wrong arg4 %x\n", a4 ); return 4321; @@ -1226,16 +1230,13 @@ static VARIANT WINAPI variant_func( int a0, BOOL a1, DECIMAL a2, VARIANT a3 )
static int CDECL void_func( int a0, int a1 ) { - if (is_win64) /* VT_EMPTY is passed as real arg on win64 */ - { - ok( a0 == 0x55555555, "wrong arg0 %x\n", a0 ); - ok( a1 == 1111, "wrong arg1 %x\n", a1 ); - } - else - { - ok( a0 == 1111, "wrong arg0 %x\n", a0 ); - ok( a1 == 0, "wrong arg1 %x\n", a1 ); - } +#ifdef __i386__ + ok( a0 == 1111, "wrong arg0 %x\n", a0 ); + ok( a1 == 0, "wrong arg1 %x\n", a1 ); +#else /* VT_EMPTY is passed as real arg on other platforms */ + ok( a0 == 0x55555555, "wrong arg0 %x\n", a0 ); + ok( a1 == 1111, "wrong arg1 %x\n", a1 ); +#endif return 12; }
@@ -1433,11 +1434,11 @@ static void test_DispCallFunc(void) res = DispCallFunc( NULL, (ULONG_PTR)void_func, CC_CDECL, VT_EMPTY, 5, types, pargs, &result ); ok( res == S_OK, "DispCallFunc failed %lx\n", res ); ok( V_VT(&result) == VT_EMPTY, "wrong result type %d\n", V_VT(&result) ); - if (is_win64) - ok( V_UI4(&result) == 12, "wrong result %08lx\n", V_UI4(&result) ); - else - ok( V_UI4(&result) == 0xcccccccc, "wrong result %08lx\n", V_UI4(&result) ); - +#ifdef __i386__ + ok( V_UI4(&result) == 0xcccccccc, "wrong result %08lx\n", V_UI4(&result) ); +#else + ok( V_UI4(&result) == 12, "wrong result %08lx\n", V_UI4(&result) ); +#endif memset( args, 0x55, sizeof(args) ); types[0] = VT_I4; V_I4(&args[0]) = 3; diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c index d920ee7c0cc..670938fb81c 100644 --- a/dlls/oleaut32/typelib.c +++ b/dlls/oleaut32/typelib.c @@ -6618,9 +6618,7 @@ __ASM_GLOBAL_FUNC( call_method, "bgt 2b\n\t" /* Loop till done */
"1:\n\t" -#ifndef __SOFTFP__ "vldm r3!, {s0-s15}\n\t" /* Load the s0-s15/d0-d7 arguments */ -#endif "mov ip, r0\n\t" /* Save the function call address to ip before we nuke r0 with arguments to pass */ "ldm r3, {r0-r3}\n\t" /* Load the r0-r3 arguments */
@@ -6642,19 +6640,15 @@ HRESULT WINAPI DispCallFunc( void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VART UINT i; DWORD *args; struct { -#ifndef __SOFTFP__ union { float s[16]; double d[8]; } sd; -#endif DWORD r[4]; } regs; int rcount; /* 32-bit register index count */ -#ifndef __SOFTFP__ int scount = 0; /* single-precision float register index count */ int dcount = 0; /* double-precision float register index count */ -#endif
TRACE("(%p, %Id, %d, %d, %d, %p, %p, %p (vt=%d))\n", pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, pvargResult, V_VT(pvargResult)); @@ -6702,11 +6696,8 @@ HRESULT WINAPI DispCallFunc( void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VART
switch (prgvt[i]) { - case VT_EMPTY: - break; case VT_R8: /* these must be 8-byte aligned, and put in 'd' regs or stack, as they are double-floats */ case VT_DATE: -#ifndef __SOFTFP__ dcount = max( (scount + 1) / 2, dcount ); if (dcount < 8) { @@ -6719,7 +6710,6 @@ HRESULT WINAPI DispCallFunc( void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VART argspos += sizeof(V_R8(arg)) / sizeof(DWORD); } break; -#endif case VT_I8: /* these must be 8-byte aligned, and put in 'r' regs or stack, as they are long-longs */ case VT_UI8: case VT_CY: @@ -6757,26 +6747,37 @@ HRESULT WINAPI DispCallFunc( void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VART --ntemp; } break; - case VT_BOOL: /* VT_BOOL is 16-bit but BOOL is 32-bit, needs to be extended */ - if (rcount < 4) - regs.r[rcount++] = V_BOOL(arg); - else - args[argspos++] = V_BOOL(arg); - break; case VT_R4: /* these must be 4-byte aligned, and put in 's' regs or stack, as they are single-floats */ -#ifndef __SOFTFP__ if (!(scount % 2)) scount = max( scount, dcount * 2 ); if (scount < 16) regs.sd.s[scount++] = V_R4(arg); else args[argspos++] = V_UI4(arg); break; -#endif + /* extend parameters to 32 bits */ + case VT_I1: + if (rcount < 4) regs.r[rcount++] = V_I1(arg); + else args[argspos++] = V_I1(arg); + break; + case VT_UI1: + if (rcount < 4) regs.r[rcount++] = V_UI1(arg); + else args[argspos++] = V_UI1(arg); + break; + case VT_I2: + if (rcount < 4) regs.r[rcount++] = V_I2(arg); + else args[argspos++] = V_I2(arg); + break; + case VT_UI2: + if (rcount < 4) regs.r[rcount++] = V_UI2(arg); + else args[argspos++] = V_UI2(arg); + break; + case VT_BOOL: + if (rcount < 4) regs.r[rcount++] = V_BOOL(arg); + else args[argspos++] = V_BOOL(arg); + break; default: - if (rcount < 4) - regs.r[rcount++] = V_UI4(arg); - else - args[argspos++] = V_UI4(arg); + if (rcount < 4) regs.r[rcount++] = V_UI4(arg); + else args[argspos++] = V_UI4(arg); break; } TRACE("arg %u: type %s %s\n", i, debugstr_vt(prgvt[i]), debugstr_variant(arg)); @@ -6786,7 +6787,6 @@ HRESULT WINAPI DispCallFunc( void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VART
switch (vtReturn) { - case VT_EMPTY: /* EMPTY = no return value */ case VT_DECIMAL: /* DECIMAL and VARIANT already have a pointer argument passed (see above) */ case VT_VARIANT: call_method( func, argspos, args, (DWORD*)®s );