oleaut32: Extend 8- and 16-bit parameters on ARM.

And update tests to show that Windows does the same.
This commit is contained in:
Alexandre Julliard 2024-04-24 16:54:48 +02:00
parent 28cb539ef9
commit fffed9b3b1
2 changed files with 39 additions and 38 deletions

View file

@ -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;

View file

@ -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*)&regs );