Skip to content

Invalid calling convention used for passing structures to varargs functions on ARM64EC #89615

@julliard

Description

@julliard

On ARM64EC, passing structures to varargs functions uses the Arm64 calling convention, but it should use the x64 convention, as documented at https://learn.microsoft.com/en-us/windows/arm/arm64ec-abi#variadic-calling-convention

Below is a short test case showing that a 5-byte structure is passed by value, but according to the ARM64EC ABI it should be passed by reference:

struct s { char a, b, c, d, e; };

extern void foo( int a, ... );

void bar(void)
{
    struct s s = { 1, 2, 3, 4, 5 };
    foo( 0, s );
}

LLVM generates this (structure contents in x1):

       0: d2804021     	mov	x1, #0x201
       4: 910003e4     	mov	x4, sp
       8: 2a1f03e0     	mov	w0, wzr
       c: f2a08061     	movk	x1, #0x403, lsl #16
      10: aa1f03e5     	mov	x5, xzr
      14: f2c000a1     	movk	x1, #0x5, lsl #32
      18: 14000000     	b	0x18 <.text+0x18>

while MSVC does this (structure contents on stack, pointer in x1):

       0: f81f0ffe     	str	x30, [sp, #-0x10]!
       4: d10043ff     	sub	sp, sp, #0x10
       8: 910003e1     	mov	x1, sp
       c: d2800000     	mov	x0, #0x0
      10: 910003e4     	mov	x4, sp
      14: d2800005     	mov	x5, #0x0
      18: 52804028     	mov	w8, #0x201
      1c: 72a08068     	movk	w8, #0x403, lsl #16
      20: b90003e8     	str	w8, [sp]
      24: 528000a8     	mov	w8, #0x5
      28: 390013e8     	strb	w8, [sp, #0x4]
      2c: 94000000     	bl	0x2c <.text$mn+0x2c>
      30: 910043ff     	add	sp, sp, #0x10
      34: f84107fe     	ldr	x30, [sp], #0x10
      38: d65f03c0     	ret

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions