Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2017-12

Double-check Linux 64-bit SSE return value handling

5 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

J. Gareth Moreton

Hi everyone,

This is not something I'm able to check myself because I don't have Linux or a suitable virtual machine installed, but according to another assembler programmer, Linux is possibly doing something weird if the return type is an array of 4 Singles (stored as a record type):

Consider the following code (Intel syntax):

type
  TGLZVector4f = packed array[0..3] of Single;
class operator TGLZVector4f.+(constref A, B: TGLZVector4f): TGLZVector4f; register; assembler; nostackframe;
asm
  MOVUPS XMM0,[A]
  MOVUPS XMM1,[B]
  ADDPS  XMM0,XMM1
  {$ifdef UNIX}
    {$ifdef CPU64}
    MOVHLPS XMM1, XMM0
    {$else}
    MOVUPS [RESULT], XMM0
    {$endif}
  {$else}
    MOVUPS [RESULT], XMM0
  {$endif}
end;

This was some vector code written by dicepd on the forum ( http://forum.lazarus.freepascal.org/index.php/topic,32741.msg267708.html#msg267708 ), and he had to do a bit of a workaround for 64-bit Linux (UNIX) because specifying "nostackframe" caused problems, namely it removed the function epilogue which, according to dicepd, was this (AT&T syntax):

movups %xmm0,-0x10(%rbp)
movq -0x10(%rbp),%xmm0
movq -0x8(%rbp),%xmm1

(MOVHLPS XMM1, XMM0 is a more efficient way of doing the same thing)

Obviously some optimisation is taking place because the compiler is recognising the structure as an array of primitive types and putting the first two into the same XMM register (rather than into 4 separate XMM registers), but then it proceeds to put the upper two Singles into a new XMM register. The rules of the x86_64 ABI - http://refspecs.linuxbase.org/elf/x86_64-abi-0.21.pdf - page 15-17, specify that the equivalent of a __float128 or __m128 should be split into two classes, with the lower half being SSE and the upper half being SSEUP, hence the two can be merged into a single XMM register.

I may be barking up the wrong tree, but it looks like a minor violation of the ABI, or at the very least, a source of unnecessary inefficiency.

Yours faithfully,

J. Gareth "Kit" Moreton

Reply by email

Jonas Maebe
to J. Gareth Moreton
J. Gareth Moreton wrote
The rules of the x86_64 ABI - http://refspecs.linuxbase.org/elf/x86_64-abi-0.21.pdf - page 15-17, specify that the equivalent of a __float128 or __m128 should be split into two classes, with the lower half being SSE and the upper half being SSEUP, hence the two can be merged into a single XMM register.

FPC does not have a way to specify equivalent types of either __float128 or __m128 at this time. FPC needs either a dedicated vector type or an array modifier (similar to "packed") to represent vector types. Otherwise it becomes very muddy regarding which types should be/are treated as vectors and which as plain plain arrays in context of ABI specifications.

Jonas

Reply by email

J. Gareth Moreton

Fair enough. I would have thought that "array[0..3] of Single" would count - granted, there's no clean way to specify a type-specific byte alignment yet, it seems.

The question came about because it looked like the lower 2 Singles were put into one XMM register and the upper 2 Singles put into another, instead of into an XMM register each, say.

Kit

On Sun 03/12/17 14:18 , Jonas Maebe sent:

Show quoted text 7 lines
On 03/12/17 01:01, J. Gareth Moreton wrote: > The rules of the > x86_64 ABI - http://refspecs.linuxbase.org/elf/x86_64-abi-0.21.pdf - page 15-17, specify that the

equivalent

Show quoted text 32 lines
> of a __float128 or __m128 should be split into two classes, with the lower half being SSE and the upper half > being SSEUP, hence the two can be merged into a single XMM register. FPC does not have a way to specify equivalent types of either __float128 or __m128 at this time. FPC needs either a dedicated vector type or an array modifier (similar to "packed") to represent vector types. Otherwise it becomes very muddy regarding which types should be/are treated as vectors and which as plain plain arrays in context of ABI specifications. Jonas _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email

Jonas Maebe
to J. Gareth Moreton
J. Gareth Moreton wrote 5 lines
Fair enough. I would have thought that "array[0..3] of Single" would count - granted, there's no clean way to specify a type-specific byte alignment yet, it seems. The question came about because it looked like the lower 2 Singles were put into one XMM register and the upper 2 Singles put into another, instead of into an XMM register each, say.

That's because the ABI specifies that arguments are passed per "eightbyte". Two 4-byte elements of an aggregate that have the same register class (SSE in this case) are merged into a single eightbyte for parameter passing (and function returning).

FWIW, a more recent version of the ABI is linked from https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI

Jonas

Reply by email

J. Gareth Moreton

Ah, thank you for clearing that up. Time for a different approach then - feature request!

Kit

On Tue 05/12/17 21:08 , Jonas Maebe sent:

Show quoted text 42 lines
On 04/12/17 13:01, J. Gareth Moreton wrote: > Fair enough. I would have thought that "array[0..3] of Single" would count - granted, there's no clean way > to specify a type-specific byte alignment yet, it seems. > > The question came about because it looked like the lower 2 Singles were put into one XMM register and the > upper 2 Singles put into another, instead of into an XMM register each, say. That's because the ABI specifies that arguments are passed per "eightbyte". Two 4-byte elements of an aggregate that have the same register class (SSE in this case) are merged into a single eightbyte for parameter passing (and function returning). FWIW, a more recent version of the ABI is linked from https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI Jonas _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email