| vcpr - code compressor for vbcc (c) in 2020 by Volker Barthelmann |
| |
| |
| @section Introduction |
| |
| vcpr is a code compressor which scans the assembly output of |
| vbcc and tries to reduce code size of the generated code by |
| moving common code sequences into separate subroutines. As a |
| trade-off, the code will usually run slower. |
| |
| Like the compiler vbcc it is split into a target independent and a |
| target dependent part. However there may be code-generators for vbcc |
| which do not have a corresponding compressor. |
| |
| This document only deals with the target independent parts of vcpr. |
| Be sure to read all the documents for your machine. |
| |
| |
| @section Usage |
| |
| Usually @command{vcpr} will be called by a frontend. However if you call it |
| directly, it has to be done like this: |
| |
| @example |
| vcpr [options] input-file output-file |
| @end example |
| |
| The following options are supported: |
| |
| @table @option |
| @item -quiet |
| Do not print the copyright notice. |
| |
| @item -debug=<n> |
| Set debug-level to <n>. |
| @end table |
| |
| |
| Note that depending on the target @command{vbcc} may insert hints into the |
| generated code. Assembly code that was not generated by @command{vbcc} |
| may not work correctly after running it through @command{vcpr}. |
| |
| |
| @section Known problems |
| |
| @itemize @minus |
| @item still in early development |
| @end itemize |
| |
| @section Backend Interface |
| |
| @subsection Building @code{vcpr} |
| |
| To write a backend for @code{vcpr}, the file @code{compress.c} has to be created |
| in the machine subdirectory. The executable @code{vcpr<target>} can be built |
| using: |
| |
| @example |
| make TARGET=<target> bin/vcpr<target> |
| @end example |
| |
| @subsection Basic Function |
| |
| @code{vcpr} first reads the assembly source into a linked list of lines. It will |
| call a backend function for each line to parse the line and fill in necessary |
| information. |
| |
| The frontend looks for identical code sequences and calculates the |
| savings that can be obtained by outlining the code. If code sequences are found |
| that provide enough savings, they will be moved to subroutines using functions |
| provided by the backend. |
| |
| Lines have to be textually identical to be considered for outlining. One exception |
| are labels. The following sequences are considered equal as long as the labels |
| are not used anywhere else: |
| |
| @example |
| |
| a |
| bne l1 |
| b |
| l1: |
| c |
| |
| a |
| bne l2 |
| b |
| l2: |
| c |
| @end example |
| |
| Currently, @code{vcpr} only supports code sequences with one label. |
| |
| @subsection Data Types |
| |
| The main data type relevant for the backend represents the attributed source lines: |
| |
| @example |
| typedef struct line @{ |
| ... |
| char *code; |
| int flags; |
| int size; |
| ... |
| int l1,l2; |
| @} line; |
| @end example |
| |
| The following members are relevant to the backend: |
| |
| @code{code} points to the assembly text of the line. |
| |
| @code{size} contains the (estimated) size of the instruction. |
| |
| @code{l1, l2} specify up to two labels referenced by this instruction. |
| |
| @code{flags} specifies the type of instruction and can be a combination of: |
| |
| @itemize |
| @item @code{LABDEF}: This line defines a label. |
| @item @code{LABUSE}: This line references a label. |
| @item @code{BARRIER}: This line must not be moved into a subroutine. |
| @item @code{LBARRIER}: Used by the frontend. |
| @end itemize |
| |
| @subsection Backend Variables |
| |
| The following variables have to be defined and initialized by the backend: |
| |
| @itemize |
| |
| @item @code{const char tg_copyright[]} |
| A copyright string. |
| |
| @item @code{int minsave;} |
| The minimum size units saved by outlining a function. Should at least be larger |
| than the size of the code for a subroutine call. |
| |
| @end itemize |
| |
| @subsection Backend Functions |
| |
| The following functions have to be provided by the backend: |
| |
| @itemize |
| |
| @item @code{void parse_line(char *s,line *p);} |
| |
| This function parses assembly line @code{s} and has to fill the |
| members @code{flags}, @code{l1}, @code{l2} and @code{size} of the line structure |
| @code{p}. |
| |
| @item @code{add_header(line *after);} |
| |
| This function creates a line for the header of outlined code and inserts it into the |
| line list. |
| |
| @item @code{add_ret(line *after);} |
| |
| This function adds a return line and inserts it into the line list. |
| |
| @item @code{add_jsr(line *after);} |
| |
| This function adds a subroutine call to the subroutine corresponding to the last |
| call of @code{add_header()}. |
| |
| @end itemize |
| |
| @subsection Frontend Functions |
| |
| The following functions are provided by the frontend and can be used by the |
| backend: |
| |
| @itemize |
| |
| @item @code{void *mymalloc(size_t sz);} |
| |
| Allocate memory. |
| |
| @item @code{int new_label(void);} |
| |
| Create a new unused label number. |
| |
| @item @code{line *new_line(void);} |
| |
| Create a new line. |
| |
| @item @code{void insert_line(line *after, line *new);} |
| |
| Insert a line into the line list at a specified position. |
| |
| @end itemize |