CONTENTS | INDEX | PREV | NEXT
COMPILER FEATURES LIST

- ANSI.  Pretty much ansi.  Please report non-ansism problems. Check out the 
KnownBugs section and release notes before reporting a problem.

- autos are placed in registers based on weighted usage.  A0,A1,D0,D1 will 
be used as register variables whenever possible, which usually reduces the 
number of registers that must be saved/restored in critical low level 
routines.  The 'register' keyword is essentially ignored but does add some 
weight to the variable for register selection. If you do not wish a variable
to be placed in a register, use the volatile storage qualifier when 
declaring the variable.

- LINK/UNLK is removed from low level routines that do not reference A5 and
do not make any subroutine calls.

- MOVEM is converted to MOVE or deleted entirely when possible.

- Various obvious optimizations:  use of BSET, BCLR, BTST as short cuts to 
logic operations, CMP/TST, etc...

- Switch() statements are optimized as follows:

 * if the range of values is less than double the number of cases a lookup
 table will be used

 * if a small number of cases exists a sub[q]/beq sequence will be used

 * for a sufficiently large set of cases that cannot be made into a jump 
 table, a binary subdivision method is used allowing huge switches to be 
 processed very quickly.

- Branch optimization.  Bxx to BRAs are optimized (up to 20 hops) by DAS, 
and massive optimization is done to multi-level conditionals by the main 
compiler pass.  branches to the next instruction are deleted entirely.

- Workbench support.  The standard startup module supports the workbench.
Specifically, the low level _main() in c.o does this. When a program is run
from the workbench, a different entry point is called: wbmain(wbmsg)

If you do not supply a wbmain() then the one from the c.lib library is used
which immediately return(-1)s, exiting the program.

The standard return from wbmain() or using exit() or _exit() automatically 
ReplyMsg()s the workbench message for you, do NOT do so manually.

- _main() shortcut for extremely low level programs.

    REFER TO THE _MAIN SECTION FOR INFORMATION ON USING THE _main()
    ENTRY POINT INSTEAD OF main().

- AutoInit support.  You may qualify a subroutine with the __autoinit 
keyword that will cause it to be automatically called by the startup code 
rather than having to explicitly call it from main.

This feature is more useful to bring code in indirectly.  For example, to 
automatically OpenLibrary() (& CloseLibrary()) floating point libraries if 
their base variables are referenced.  However, it can also be used for 
independant module initialization.  Note that stdio is NOT up and running 
at this time.

Refer to the auto.lib source code for examples.

__autoexit works the same way.  Note that __autoinit routines are called 
BEFORE _main, just after autoinit libraries are openned, and __autoexit 
routines are called in __exit just before autoinit libraries are closed.

- DCC runs fast.  Make everything resident and watch it fly.  Most of this 
speed comes from loading entire files into memory at once. This might 
present a memory problem, but in general DICE's memory usage is comparable 
to Lattice and Aztec.

- CODE SIZE is comparable with Lattice and Aztec, even better in many cases.
The minimum program sizes are as follows:

_main() { }          448    no stdio/fd
 main() { }         2736    some stdio
 main() { printf..} 5492    most of stdio

(12) EXTENSIONS , see EXTENSIONS.DOC.  DICE provides many extensions
 to C to support various AMIGAisms and ROM based code, including
 special treatment of the 'const' storage qualifier.

(13) The preprocessor is able to handle arbitrarily sized macros.  There
 are no limits to symbol or macro length.  The preprocessor is able to
 handle up to 64 levels of includes / macro recursions with arbitrary
 use of the string-ize (#) and token pasting (##) operators.

 The preprocessor implements the __BASE_FILE__ macro as well as all
 standard ANSI macros (__FILE__, __LINE__, __DATE__, __TIME__, ...)

(14) DICE supports the creation of residentable executables in nearly
 all cases (exception: using the __geta4 procedure qualifier
 precludes being able to make an executable resident, also non
 const __chip data... see EXTENSIONS.DOC)

 Not only is residentability supported, but it is supported
 without requiring the programmer to #include all sorts of
 prototype/pragma files.

(15) DICE supports the small-data model, large data model, small and
 large code models, and special data models (word absolute,
 absolute known address) for supporting ROMable code.  The linker
 automatically generates JMP tables when the small-code model is
 used in large executables.

(16) REGISTERED user's DICE supports __chip, __near, and __far keywords,
 as well as many others.

(17) Simplified library and startup module design.  There are no multiple
 versions of a single library for different memory models and the
 frontend, DCC, makes all library and startup module interaction
 except m.lib invisible.  The same c.o handles both resident and
 non-resident startup.  c.lib and m.lib may be used with programs
 that declare more than 64KBytes of BSS (though not with programs
 that declare more than 64KBytes of __near initialized storage).

 There is no large-data-model version of c.lib and m.lib,
 although you can easily recompile the libraries into a large-data
 model version if you wish.  I suggest that instead of doing that
 you stick with the small-data model and use the __geta4 type
 qualifier to procedures which are called out of context.

 The registered dist contains several source examples for libraries,
 dos handlers, exec devices, and printer drivers.

 (18) Optimization of args to prototyped routines