On 01.09.2013 20:21, Bernd Oppolzer wrote:
As I understand it now, we have several levels of the compiler:

a) scanning and parsing the source code, which leads to a "tree
representation"
of the units, which IMO is a kind of in-storage-representation of the
source code
(and tables etc.), without much dependencies of the target, if any. I
don't think,
that informations about available registers etc. of the target machine
are necessary
at this level.

Correct. There are only very few exceptions, e.g. on m68k-amiga you can use the "location" keyword to specify a register location for a parameter or the result value (whereby of course you need to know which registers are available).

b) the "tree representation" is translated into a "linear assembly
list", which is
target specific; from previous posts it sounds as if there are generic
methods
which help with this, and those methods of course need information about
the
target platform - but there is no "intermediate language" at this stage
like
in the P-Code case. (I know of other compilers, namely the IBM commercial
ones, which translate in this stage for an abstract target machine which
has
an arbitrary number of registers, and the later "real" code generator
puts it
down to the real number, for example 16, and the missing registers are
simulated in storage). This needs to be examined more.

It looks like this: all nodes are classes that descend from the tnode class. E.g. for adding two values (ordinals or floats) there is the taddnode which descends from tbinarynode which in turn descends from tnode. This taddnode does the general type checking and often also determines whether the result will be passed in a register, as memory reference or whatever. Then there is the tcgaddnode which descends from taddnode and is either able to provide a platform independant implementation (not the case for taddnode) which uses the general interface of the code generator or at least provides a few platform specific helpers and splits the implementation up a bit (in this case tcgaddnode provides methods "second_addfloat", "second_cmpfloat", "second_addordinal", etc. which can be implemented by the platform specific node which is (in case of ARM) called tarmaddnode and is a descendant of tcgaddnode. This node usually uses the platform specific taicpu to generate the abstract assembler instructions.

This seems a bit abstract at first, but with time you get a feeling for it...

c) the "linear assembly list" is written to files, more or less without
changes

Whereby the specified assembler writer is used.

d) the files are assembled using an external assembler (in our case);
it must be callable from the FPC compiler. There exists an interface for
gas;
interfaces to other assemblers have to be built.

gas is only one example. There are interfaces for a few other assemblers as well (mostly on i386, but e.g. on ppc-macos (Classic Mac OS) we use the Apple specific assembler tool)

e) in the same way an external linker is used to link the units together.

Correct.

Regards,
Sven
_______________________________________________
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to