2830 lines · 101.9 KB · Text
RawDownload
 @section Introduction This chapter is under construction!      This chapter describes some of the internals of @command{vbcc} and tries to explainwhat has to be done to write a code generator for @command{vbcc}.However if someone wants to write one, I suggest to contact me first,so that it can be integrated into the source tree. You have to create a new directory for the new target named@file{machines/<target-name>} and write the files @file{machine.c}, @file{machine.h}and @file{machine.dt}. The compiler for this target will be called@command{vbcc<target-name>} and can be built doing a@command{make TARGET=<target-name> bin/vbcc<target-name>}. From now on integer means any of @code{char, short, int, long, long long} or theirunsigned couterparts. Arithmetic means integer or @code{float} or @code{double} or @code{long double}.Elementary type means arithmetic or pointer. Note that this documentation may mention explicit values when introducingsymbolic constants. This is due to copying and pasting from the sourcecode. These values may not be up to date and in some cases can be overridden.Therefore do never use the absolute values but rather the symbolicrepresentations.  @section Building vbcc This section deals with the steps necessary to build the typical@command{vbcc} executables from the sources. @subsection Directory Structure     The vbcc-directory contains the following important files and    directories:@table @file@item    vbcc/The main directory containing the compiler sources. @item    vbcc/MakefileThe Makefile used to build @command{vbcc}. @item    vbcc/frontend/Directory containing the source to @command{vc}, the compiler driver. @item    vbcc/machines/<target>/Directory for the @code{<target>} backend. @item    vbcc/machines/ucpp/Directory containing the builtin preprocessor. @item    vbcc/vsc/Directory containing source to @command{vsc}, the instruction scheduler. @item    vbcc/bin/Directory the executables will be placed in.@end table     All compiling is done from the main directory.    The frontend @command{vc} is not target-dependend and therefore only one version    is created.     Every available target has at least one subdirectory with its name in    @file{vbcc/machines} and contains at least the files @file{machine.h}, @file{machine.c} and    @file{machine.dt}. Target-specific object-files will also be stored in that    directory.     The executables will be placed in @file{vbcc/bin/}. The main compiler will    be called @command{vbcc<target>}.  @subsection Adapting the Makefile     Before building anything you have to insert correct values for    @code{CC, NCC, LDFLAGS} and @code{NLDFLAGS} in the @file{Makefile}. @table @code    @item CC       Here you have to insert a command that invokes an ANSI C             compiler you want to use to build vbcc. It must support             @option{-D}, @option{-I}, @option{-c} and @option{-o}                 the same like e.g. @command{vc} or @command{gcc}.             Additional options should also be inserted here. E.g. if you             are compiling for the Amiga with @command{vbcc} you should add                 @option{-DAMIGA}.     @item LDFLAGS          Here you have to add options which are necessary for linking.             E.g. some compilers need special libraries for floating-point.     @item NCC    @itemx NLDFLAGS    These are similar to @code{CC} and @code{LDFLAGS} but they must always    describe a native compiler, i.e. Programs compiled with @code{NCC/NLDFLAGS}    must be executable on the host system. This is needed because during    the build programs may have to be executed on the host.@end table     An example for the Amiga using @command{vbcc} would be:@example      CC = vc -DAMIGA -c99      LDFLAGS = -lmieee      NCC = $(CC)      NLDFLAGS = $(LDFLAGS)@end example     An example for a typical Unix-installation would be:@example      CC = cc      LDFLAGS = -lm      NCC = $(CC)      NLDFLAGS = $(LDFLAGS)@end example The following settings are probably necessary for Open/Free/Any BSD i386 systems:@example      CC = gcc -D_ANSI_SOURCE      LDFLAGS = -lm      NCC = $(CC)      NLDFLAGS = $(LDFLAGS)@end example  @subsection Building vc Note to users of Open/Free/Any BSD i386 systems: You will probably have to useGNU make instead of BSD make, i.e. in the following examples replace "make"with "gmake".     Type:@example      make bin/vc@end example @subsection Building vsc     Type:@example      make TARGET=<target> bin/vsc<target>@end example    For example:@example      make TARGET=alpha bin/vscalpha@end example     Omit this step if there is no file @file{machines/<target>/schedule.c}.  @subsection Building vbcc     Type: @example      make TARGET=<target> bin/vbcc<target>@end exampleFor example:@example      make TARGET=alpha bin/vbccalpha@end example     During the build the program @command{dtgen} will be generated and executed on    the host-system. First it will ask you whether you are building a    cross-compiler.     Answer @code{y} only if you are building a cross-compiler (i.e. a compiler    which does not produce code for the same machine it it running on).     Note that it does _not_ matter if you are cross-building a compiler,    i.e. if you are running on system A and building a B->B compiler    by using an A->B compiler then you can answer @code{n}.     If you answered @code{y} you will be asked if your system/compiler offers    certain datatypes. This refers to the compiler you described with    CC in the Makefile.    E.g. if @code{CC} is an A->B cross-compiler you have to answer the questions    according to B.    To each question answer @code{y} or @code{n} depending if such a datatype is    available on that compiler. If you answered @code{y} you have to type in    the name of that type on the compiler (e.g. @code{signed int},    @code{unsigned char} etc.).    If there are not enough datatypes available to build @command{vbcc}    an error    message will be printed and the build aborts.  @subsection Configuring     Consult the @command{vbcc}-documentation for information on    how to create the necessary config-files.  @subsection Building Cross-Compilers     As there is often confusion when it comes to cross-building compilers    or building cross-compilers, here is what has to be done to cross-build    a B->C cross-compiler on system A with only a native A->A compiler    available.     This is done by first building an A->B compiler and then cross-building    the B->C compiler using the A->B compiler.     For the first step you use the A->A compiler for @code{CC} as well as        @code{NCC}.    Now you type:@example      make bin/vc      make TARGET=B bin/vscB   # omit if there is no machines/B/schedule.c      make TARGET=B bin/vbccB@end example     The questions about datatypes are answered according to A.    Then you should write a @file{vc.config} for the @code{vbccB} cross-compiler.     Now create a second directory containing all the sources to @command{vbcc} and    set @code{CC/LDFLAGS} to @command{vc} using the config-file for vbccB and        @code{NCC/NLDFLAGS}    to the A->A compiler. Type:@example      make bin/vc      make TARGET=C bin/vscC   # omit if there is no machines/C/schedule.c      make TARGET=C bin/vbccC@end example   @section The Intermediate Code @command{vbcc} will generate intermediate code for every function and passthis code to the code generator which has to convert it into the desired output. In the future there may be a code generator generator which reads a machinedescription file and generates a code generator from that, but it is notclear whether this could simplify much without taking penalties in thegenerated code.Anyway, this would be a layer on top of the current interface to the codegenerator, so that the interface described in this document would still bevalid and accessible. @subsection General Format The intermediate code is represented as a doubly linked list of quadruples(I am calling them ICs from now on) consisting mainly of an operator, twosource operands and a target. They are represented like this: @example struct IC@{    struct IC *prev;    struct IC *next;    int code;    int typf;    int typf2;    [...]    struct obj q1;    struct obj q2;    struct obj z;    [...]    struct ext_ic ext;  /* optional */@};@end example The only members relevant to the code generator are@code{prev, next, code, typf, typf2, q1, q2, z} and (optionally) @code{ext_ic}. @code{prev} and @code{next} are pointers to the previous and next IC.The first IC has @code{prev==0} and the last one has @code{next==0}. @code{typf} and @code{typf2} are the type of the operands of this IC.In most ICs all operands have the same type and therefore only @code{typf}is used. However, some ICs have operands of different types (e.g.converting an operand to another type or adding an integer to a pointer).@code{typf2} is used in these cases. Macros are provided which yield the type of an operand.@code{q1typ(), q2typ()} and @code{ztyp()} return the type of the first sourceoperand, the second source operand and the destination, respectively.They have to be passed a pointer to a valid IC as argument. The results areundefined if the IC does not contain the specified operand (e.g. @code{q2typ()}for an IC with only a single operand). The standard types which are defined by default are: @example    #define CHAR     #define SHORT     #define INT     #define LONG     #define LLONG    #define FLOAT     #define DOUBLE     #define LDOUBLE    #define VOID     #define POINTER     #define ARRAY     #define STRUCT     #define UNION     #define ENUM          /*  not relevant for code generator     */    #define FUNKT @end example     and can be additionally or'ed by @example    #define UNSIGNED    #define CONST    #define VOLATILE    #define UNCOMPLETE@end example     However, only @code{UNSIGNED} is of real importance for the code generator.    @code{typf&NQ} yields the type without any qualifiers, @code{typf&NU}    yields the type without any qualifiers but @code{UNSIGNED}. It is possible for backends to define additional types. @xref{exttypes}for documentation on how to extend the type system. @node operands@subsection Operands @code{q1, q2} and @code{z} are the source1 (quelle1 in German), source2 andtarget (ziel) operands, respectively.If a result has to be computed, it always will be stored in the object @code{z}and the objects @code{q1} and @code{q2} usually may not be destroyed duringthis operation (unless they are aliased with the destination). The objects are described by this structure: @example struct obj@{    int flags;    int reg;    int dtyp;    struct Var *v;    struct AddressingMode *am;    union atyps@{        zchar vchar;        zchar vuchar;        zshort vshort;        zushort vushort;        zint vint;        zuint vuint;        zlong vlong;        zulong vulong;        zllong vllong;        zullong vullong;        zmax vmax;        zumax vumax;        zfloat vfloat;        zdouble vdouble;        zldouble vldouble;    @} val;@}; @end example @code{flags} specifies the kind of object. It can be a combination of @table @code @item #define KONST 1    The object is a constant. Its value is in the corresponding (to        @code{typf} or @code{typf2})    member of @code{val}. @item #define VAR 2    The object is a variable. The pointer to its @code{struct Var} is in     @code{v}. @code{val.vlong} vontains an offset that has to be added to it.    Fur further details, @pxref{Variables}. @item #define DREFOBJ 32    The content of the location in memory the object points to is used.        @code{dtyp} contains the type of the pointer. In systems with        only one pointer type, this will always be @code{POINTER}. @item #define REG 64    The object is a register. @code{reg} contains its number. @item #define VARADR 128    The address of the object is to be used. Only together with static    variables (i.e. @code{storage_class == STATIC} or @code{EXTERN}). @end table The possible combinations of these flags should be: @itemize        @item @code{0} (no object)        @item @code{KONST}        @item @code{KONST|DREFOBJ}        @item @code{REG}        @item @code{VAR}        @item @code{VAR|REG}        @item @code{REG|DREFOBJ}        @item @code{KONST|DREFOBJ}        @item @code{VAR|DREFOBJ}        @item @code{VAR|REG|DREFOBJ}        @item @code{VAR|VARADR}@end itemize Also some other bits which are not relevant to the code generator may be set. Constants will usually be in @code{q2} if possible. One of the sources alwaysis not constant and the target is always an lvalue.The types of the operands can be queried using the macros@code{q1typ(), q2typ()} and @code{ztyp()}.In most cases (i.e. when not explicitly stated) the type is an elementary type(i.e. arithmetic or pointer). @code{am} can be used to store information on special addressing modes.This has to be handled by the by the code generator. However @code{am} has to be 0or has to point to a @code{struct AddressingMode} that was allocated using @code{malloc()}when the code generator returns. @code{struct AddressingMode} has to be definedin @file{machine.h}. @code{val} stores either the value of the object if it is a constant or anoffset if it is a variable. @code{code} specifies the operation. Fur further details @pxref{operations}.   @node Variables@subsection Variables     A @code{struct Var} looks like: @example     struct Var@{        int storage_class;        [...]        char *identifier;        [...]        zmax offset;        struct Typ *vtyp;        [...]        char *vattr;        unsigned long tattr;   /* optional */    @};@end example      The relevant entries are: @table @code    @item identifier        The name of the variable. Usually only of interest for variables        with external-linkage.     @item storage_class        One of:        @example            #define AUTO 1            #define REGISTER 2            #define STATIC 3            #define EXTERN  4            #define TYPEDEF 5       /*  not relevant    */        @end example        The backend should use the macros @code{isauto(), isstatic()}        and @code{isextern()} to check which category a variable falls into.      @item offset        Contains an offset relative to the beginning of the variable's        storage. Used, for example, when accessing members of structures.      @item vtyp        The type of the variable (@pxref{compositetypes}).      @item vattr        A string with attributes used in the declaration of the variable.        @xref{targetattributes} for further details.      @item tattr        Flags used when declaring the variable.        @xref{targetattributes} for further details.@end table         If the variable is not assigned to a register (i.e. bit @code{REG}        is not set in the flags of the corresponding @code{struct obj}) then        the variable can be addressed in the following ways (with        examples of 68k-code): @table @code        @item isauto(storage_class) != 0            @code{offset} contains the offset inside the local-variables            section. The code generator must decide how it's going to handle            the activation record.            If @code{offset < 0} then the variable is a function argument on                the

Lines 1–500 of 2830.