Sign in Join

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

Mailing lists / fpc-devel / 2019-03

Successful implementation of inline support for pure assembler routines on x86

5 messages · 5 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,

Sorry for the slightly long-winded title.  This was something I've been working on for the past few weeks to allow the use of "inline" with certain x86 assembler routines, subject to restrictions for safety reasons.  I have successfully written code that implements this support while ensuring it doesn't affect platforms with a different assembly languages.  Regression tests have passed, as have some new tests, some of which test modified RTL assembler functions that have had "inline" added to their list of directives.

There was a previous concern about it breaking too much and it being impossible to implement on all platforms - the latter point may be true, but through the careful use of virtual methods within the compiler, it should be possible to extend the inline support one platform at a time without breaking the others.
All the details, including a PDF specification that explains the design and implementation choices, a couple of existing tests that touch on the functionality, along with any new tests, limitations or problems found, can be found here: https://bugs.freepascal.org/view.php?id=35232 I hope it proves to be insightful and useful.
Gareth aka. Kit

P.S. Though this feature can be used for implementing intrinsics, it is not a direct replacement for them because instructions like SHUFPS cannot be flexibly encoded due to its immediate operand (i.e. it has to be a raw number... it can't take its value from a parameter).

Reply by email

Sven Barth
to J. Gareth Moreton

J. Gareth Moreton schrieb am Fr., 15. März
2019, 12:33:

Show quoted text 5 lines
P.S. Though this feature can be used for implementing intrinsics, it is not a direct replacement for them because instructions like SHUFPS cannot be flexibly encoded due to its immediate operand (i.e. it has to be a raw number... it can't take its value from a parameter).

That could maybe be managed once the support for constants as parameter for generics is added (note: I don't know right now how SHUFPS works, so take the following as pseudo code):

=== code begin ===

generic function ShufPS<const N: Integer>(aArg: Whatever): Whatever; inline;
begin
  asm
    SHUFPS %xmm1, %xmm2, N
  end;
end;

=== code end ===

As long as the assembler reader correctly handles constants for those parameters this could work as for each N the compiler creates a new function...

Regards,
Sven

Reply by email

Ryan Joseph
to Sven Barth
On Mar 15, 2019, at 9:37 AM, Sven Barth via fpc-devel wrote: That could maybe be managed once the support for constants as parameter for generics is added (note: I don't know right now how SHUFPS works, so take the following as pseudo code):

I fixed the patch for constants in generics and uploaded again (https://bugs.freepascal.org/view.php?id=35140). Not sure if they added it yet or they were waiting for my to fix things. Let me know if that patch is in the correct format so I can fix the other one for multi-helpers.

Regards,
Ryan Joseph

Reply by email

Florian Klämpfl
to J. Gareth Moreton: Sorry for the slightly long-winded title.  This was something I've been working on for…
J. Gareth Moreton wrote 10 lines
Hi everyone, Sorry for the slightly long-winded title.  This was something I've been working on for the past few weeks to allow the use of "inline" with certain x86 assembler routines, subject to restrictions for safety reasons.  I have successfully written code that implements this support while ensuring it doesn't affect platforms with a different assembly languages.  Regression tests have passed, as have some new tests, some of which test modified RTL assembler functions that have had "inline" added to their list of directives.

As said before, I have a lot of concerns against this as it opens a can of worms hard to handle:
* using inline assembler is always the worst solution to do something, it normally means either:
- the compiler misses a certain feature
- the compiler is generating bad code
* intrinsics provide a much better way to achieve exactly what this approach aims at:
- they enable the use of all registers as the compiler does register allocation
- constraints on instructions (like a certain operand needs to be a constant) can be easily forced

Is there any advantage over intrinsics, I missed so far?

Show quoted text 20 lines
There was a previous concern about it breaking too much and it being impossible to implement on all platforms - the latter point may be true, but through the careful use of virtual methods within the compiler, it should be possible to extend the inline support one platform at a time without breaking the others. All the details, including a PDF specification that explains the design and implementation choices, a couple of existing tests that touch on the functionality, along with any new tests, limitations or problems found, can be found here: https://bugs.freepascal.org/view.php?id=35232 I hope it proves to be insightful and useful. Gareth aka. Kit P.S. Though this feature can be used for implementing intrinsics, it is not a direct replacement for them because instructions like SHUFPS cannot be flexibly encoded due to its immediate operand (i.e. it has to be a raw number... it can't take its value from a parameter).

Well, with intrinsics, this can be easily done.

Reply by email

Marģers .
to Florian Klämpfl

 

----- Reply to message -----
Subject: Re: [fpc-devel] Successful implementation of inline support for pure assembler routines on x86 Date: 2019. gada 17. marts 19:38:03
From: Florian Klämpfl
To:

Show quoted text 5 lines
Am 15.03.19 um 11:32 schrieb J. Gareth Moreton: * using inline assembler is always the worst solution to do something, it normally means either: - the compiler misses a certain feature

Question is about, who is going to implement every imaginable feature in reasonable time frame? For
example intrinsics for BMI.

- the compiler is generating bad code

Generated code for x86_64 instruction set is
pretty good, if pascal code is tuned to take
advantaged of optimization currently done by
compiler (LLVM target does not do any better). But assembler still give 10-20% boost. So there is
still space for improvements.

Show quoted text 6 lines
* intrinsics provide a much better way to achieve exactly what this approach aims at: - they enable the use of all registers as the compiler does register allocation

sadly it does not apply to bsf

Is there any advantage over intrinsics, I missed so far?

To take advantage of flags changed by instruction.

I looking forward for assembler inline
functionality to be accepted. I would benefit of it.

Reply by email