Forum > General

possible to add inlined CPU-specific assembly language instructions?

(1/4) > >>

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.

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.

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.

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;
        y : qword;
                bsr x,y
        bsr := y;

        a, b : qword;

        a := 65;
        b := bsr(a);

$ 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

Also i didn't think to check the System unit for intrinsics.  I'll look into that and perhaps see how they are implemented.


[0] Message Index

[#] Next page

Go to full version