Recent

Author Topic: possible to add inlined CPU-specific assembly language instructions?  (Read 9311 times)

tyates

  • Newbie
  • Posts: 3
My question is does anyone know if it is possible to use processor specific statements in Pascal code, ideally via an inlined function call.

Modern x86 CPUs have PREFETCH, LFENCE/MFENCE, CMOV, SETcc, all the SSE instructions, etc.  In free pascal, if I create a function with inline assembly and then try to inline that function I get an error specifically saying I can't do that (inline assembly / inline function).  Perhaps the instruction scheduler or register allocator can't deal with the complexity.

Another possibility I was thinking is that perhaps the machine-specific components of the back-end compiler that have the ability to select instructions may also have the capability to support new assembly language instructions and have them exposed to the developer in some way.  I think I've seen config files with lists of instructions before.  If this would require extending the compiler I'm willing to look at that possibility.

I know the standard response to someone who is looking for performance is "why do you need speed CPUs are fast enough blah blah". Please understand that my interest is in understanding and demonstrating how to expose the underlying performance of the CPU to the user in a high level language in library code like memory allocators and parallel data structures.

Another definition of the problem is that the instruction set of a modern x86 CPU is much broader than you can express in a typical language statement.  In C/gcc the problem is kludged using inline assembly statements that describe what registers you want to preserve, and then inlining those function calls.  In C++/gcc these can be wrapped in templated functions and classes to create fairly elegant solutions (hopefully).  I really like Pascal and would hope to do some of the same type of thing using Generics.

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2285
    • havefunsoft.com
Re: possible to add inlined CPU-specific assembly language instructions?
« Reply #1 on: June 13, 2014, 08:29:09 pm »
Assembler is not allowed at the inline functions.
But you should still have an ability to add assembler within regular function or create pure assembler functions.

Could you please provide an example code that doesn't compile for you? It might be something that could be added into the compiler trunk.
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7510
Re: possible to add inlined CPU-specific assembly language instructions?
« Reply #2 on: June 14, 2014, 12:30:02 am »
FPC currently doesn't support a wide range of intrinsics for every asm instruction conceivable, and does not allow inlining of assembler or a register independent (node) syntax.

Afaik there is support for prefetch(w) as intrinsic though, and cmov and setcc are generated if they are faster and the correct instruction set is selected (686+).

If you want to work on it, there are three directions I guess:

  • implement a framework for bulk intrinsics
  • enhance the assembler parser to detect destroyed registers, deal with branches while inlining assembler. And implement it of course
  • Introduce a new assembler syntax with metadata to allow the programmer to create inlinable assembler. And implement it of course


Serious talk about compiler development is best done on the fpc-devel maillist.
« Last Edit: June 14, 2014, 02:37:10 am by marcov »

tyates

  • Newbie
  • Posts: 3
Re: possible to add inlined CPU-specific assembly language instructions?
« Reply #3 on: June 14, 2014, 02:04:20 pm »
Ok I'll head there - thanks.

I did work on an example but haven't got the assembly portion to compile yet.  This uses the BSR instruction (bit scan right).

program First;

function bsr(x : qword) : qword inline;
var
        y : qword;
begin
        asm
                bsr x,y
        end;
        bsr := y;
end;

var
        a, b : qword;

begin
        a := 65;
        b := bsr(a);
        writeln(b);
end.

$ fpc test3.pas
Free Pascal Compiler version 2.6.0 [2011/12/30] for i386
Copyright (c) 1993-2011 by Florian Klaempfl and others
Target OS: Darwin for i386
Compiling test3.pas
test3.pas(11,4) Warning: "assembler" not yet supported inside inline procedure/function
test3.pas(11,4) Warning: Inlining disabled
test3.pas(8,9) Error: Asm: [bsr mem64,mem64] invalid combination of opcode and operands
test3.pas(21) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted
Error: /usr/local/bin/ppc386 returned an error exitcode


tyates

  • Newbie
  • Posts: 3
Re: possible to add inlined CPU-specific assembly language instructions?
« Reply #4 on: June 14, 2014, 02:11:37 pm »
Also i didn't think to check the System unit for intrinsics.  I'll look into that and perhaps see how they are implemented.

Laksen

  • Hero Member
  • *****
  • Posts: 621
    • J-Software
Re: possible to add inlined CPU-specific assembly language instructions?
« Reply #5 on: June 14, 2014, 04:37:19 pm »
The BSR and BSF instructions have intrinsic functions(and emulated functions on unsupported architectures): BsrQWord, and other variations

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7510
Re: possible to add inlined CPU-specific assembly language instructions?
« Reply #6 on: June 14, 2014, 05:05:03 pm »
Intrinsics generally don't have a RTL implementation their code is generated in the compiler codegenerator.

Bloody mess

  • Newbie
  • Posts: 3
Re: possible to add inlined CPU-specific assembly language instructions?
« Reply #7 on: January 21, 2015, 08:57:25 pm »
Is there any chance that "assembler inside inline procedure/function" support would be added? It's very sadly and makes me crying sometimes. I even think to use gcc instead.

"enhance the assembler parser to detect destroyed registers, deal with branches while inlining assembler. And implement it of course" - I would like to do this, but do not know how, unfortunately. And I don't get why need to detect destroyed registers, I always save and restore used registers, for example.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7510
Re: possible to add inlined CPU-specific assembly language instructions?
« Reply #8 on: January 22, 2015, 10:48:11 am »
Is there any chance that "assembler inside inline procedure/function" support would be added? It's very sadly and makes me crying sometimes.

There is always any chance, simply because somebody could suddenly turn up and submit a patch.  But I don't think it is on current roadmaps.

Note that there are are several ways to do this. Going the assembler centric way as you say, or going a more modern way introduction a node syntax (like LLVM) or register independent syntax like GCC.

Or, if we take to the spirit of the early part of this thread, expand the intrinsics support.

Quote
I even think to use gcc instead.

Afaik GCC doesn't either, it requires a special format.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8112
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: possible to add inlined CPU-specific assembly language instructions?
« Reply #9 on: January 22, 2015, 12:49:35 pm »
Afaik GCC doesn't either, it requires a special format.
with
Code: [Select]
__attribute__((always_inline));it does.

Basile B.

  • Guest
Re: possible to add inlined CPU-specific assembly language instructions?
« Reply #10 on: January 22, 2015, 02:32:16 pm »
My question is does anyone know if it is possible to use processor specific statements in Pascal code, ideally via an inlined function call.

Modern x86 CPUs have PREFETCH, LFENCE/MFENCE, CMOV, SETcc, all the SSE instructions, etc.  In free pascal, if I create a function with inline assembly and then try to inline that function I get an error specifically saying I can't do that (inline assembly / inline function).

Maybe I completly miss the point but if your problem is about missing assembly instruction then don't forget that you can also directly program using x86 byte code:

e.g, instead of MOV result,$01:

Code: [Select]
program Project1;
uses sysutils;
{$ASSERTIONS+}
{$ASMMODE INTEL}
function example: boolean; assembler;
asm
  DB $B0;
  DB $01;
end;
begin
  assert(example(),'not true');
  readln;
end.

To be clear, you can use this trick to put the instructions which are not recognized.

For example some people uses this to put the instruction RDTSC in very old delphi versions, since when the compiler was shipped this CPU instruction didn't existed.
« Last Edit: January 22, 2015, 02:50:08 pm by Basile B. »

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7510
Re: possible to add inlined CPU-specific assembly language instructions?
« Reply #11 on: January 22, 2015, 03:27:18 pm »
Afaik GCC doesn't either, it requires a special format.
with
Code: [Select]
__attribute__((always_inline));it does.

Does it force inline then, or really scan the inline asm code for used registers as requested?
« Last Edit: January 22, 2015, 03:31:19 pm by marcov »

Laksen

  • Hero Member
  • *****
  • Posts: 621
    • J-Software
Re: possible to add inlined CPU-specific assembly language instructions?
« Reply #12 on: January 22, 2015, 03:40:20 pm »
You specify operands in a gcc specific way. It's nothing like the inline assembly in fpc.

Unless something like that gets added to fpc it won't be possible to inline such stuff. All instructions would need precise semantic definitions otherwise. Like what does it change in the status register, does it modify edx, other weird stuff, etc. And there are many hundred or instructions to do that with

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7510
Re: possible to add inlined CPU-specific assembly language instructions?
« Reply #13 on: January 22, 2015, 03:54:42 pm »
You specify operands in a gcc specific way. It's nothing like the inline assembly in fpc.

Ok, so it is the same as the already mentioned register-independent asm. with all the funny looking modifiers that specify what's changed?


Leledumbo

  • Hero Member
  • *****
  • Posts: 8112
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: possible to add inlined CPU-specific assembly language instructions?
« Reply #14 on: January 22, 2015, 05:59:54 pm »
Does it force inline then, or really scan the inline asm code for used registers as requested?
Force inline, no register usage scanning seems done. Maybe could break something when used improperly.