[foreign-memaccess+abi] RFR: 8295290: Add Windows ARM64 ABI support to the Foreign Function & Memory API [v2]

Saint Wesonga duke at openjdk.org
Tue Jan 10 06:41:26 UTC 2023


On Fri, 6 Jan 2023 02:14:36 GMT, Jorn Vernee <jvernee at openjdk.org> wrote:

>> Saint Wesonga has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains ten commits:
>> 
>>  - Merge branch 'foreign-memaccess+abi' into WindowsAArch64ABI
>>  - Update Windows FFM implementation to match latest Preview API
>>  - Merge branch 'foreign-memaccess+abi' into WindowsAArch64ABI
>>  - Simplify newly added tests in TestVarArgs
>>  - Move storage decisions into StorageCalculator
>>  - Remove toSessionImpl method
>>  - Remove unnecessary null check
>>  - Move Windows CallArranger tests into separate file
>>  - Add Windows ARM64 ABI support to the Foreign Function & Memory API
>>    
>>    There are 2 primary differences between the Windows ARM64 ABI and
>>    the macOS/Linux ARM64 ABI: variadic floating point arguments are passed
>>    in general purpose registers on Windows (instead of the vector registers).
>>    In addition to this, up to 64 bytes of a struct being passed to a
>>    variadic function can be placed in general purpose registers. This
>>    happens regardless of the type of struct (HFA or other generic struct).
>>    This means that a struct can be split across registers and the stack
>>    when invoking a variadic function.
>>    
>>    This change introduces tests that compute the sum of the fields of
>>    structs containing 1-4 ints, floats, and doubles to verify that each
>>    field is correctly assigned a register or stack location when invoking
>>    a variadic function (both when the struct can be passed entirely in
>>    registers as well as when the struct spills onto the stack).
>>    
>>    For details about the Foreign Function & Memory API, see JEP 434
>>    defined at https://openjdk.org/jeps/434
>>    
>>    The Windows ARM64 ABI conventions are documented at
>>    https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions
>
> src/java.base/share/classes/jdk/internal/foreign/abi/aarch64/CallArranger.java line 263:
> 
>> 261: 
>> 262:         VMStorage[] regAlloc(int type, MemoryLayout layout) {
>> 263:             boolean spillRegistersPartially = forVariadicFunction && spillsVariadicStructsPartially();
> 
> Just be sure here, this would make it so that any struct passed to a variadic function is spilled partially, even if that particular struct is not being passed as a variadic argument.
> 
> Is that correct?

Yes, that is correct. An HFA with 4 floats that is the last non-variadic argument after 6 other non-variadic arguments will have half of it passed in x7 and half at [sp].

> src/java.base/share/classes/jdk/internal/foreign/abi/aarch64/CallArranger.java line 287:
> 
>> 285:             if (type == StorageType.VECTOR) {
>> 286:                 boolean forVariadicFunctionArgs = forArguments && forVariadicFunction;
>> 287:                 boolean useIntRegsForFloatingPointArgs = forVariadicFunctionArgs && useIntRegsForVariadicFloatingPointArgs();
> 
> Same here I suppose. On Windows/x64 we pass vardiadic floats both in float registers and int registers, but only variadic floats. But, this seems to make it so that any float being passed to a variadic function, even as fixed argument, is passed in an int register.

Yes, Windows on ARM64 requires these floats to be in integer registers when calling variadic functions.

-------------

PR: https://git.openjdk.org/panama-foreign/pull/754


More information about the panama-dev mailing list