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