Article View: comp.sys.amiga.tech
Article #3710Re: DICE
From: Matthew Dillon
Date: Thu, 31 May 1990 00:24
Date: Thu, 31 May 1990 00:24
135 lines
7378 bytes
7378 bytes
>In article <9005290344.AA10362@thunder.LakeheadU.Ca> tjhayko@THUNDER.LAKEHEADU.CA writes:
>
>Welcome back to the net, Matt. I'm interested in what some of the features of
>you DICE C Compiler are. How does it compare with commerical compilers? or
>other Public Domain/Shareware offerings? What does it include in the package?
*FAST*, clean compilation is the main thing. The DICE system includes
nearly everything required to generate an executable, editor (DME),
front-end (DCC), preprocessor (DCPP), main-compiler (DC1), a minimal
assembler (DAS), linker (DLINK), c.lib (+ source to c.lib), ANSI includes,
all written by yours truely! I have even managed to write most of the
time handling routines.
You need to get amiga.lib and the 1.3 includes from commodore
separately, at least until I get my redistribution license for that
stuff. Or you can simply use the amiga.lib and 1.3 includes that comes
with Lattice/Aztec if you have either of those compilers.
As I say in the documentation, this is the first major release of DICE
and it does not support everything yet... floating point and bit
fields, for example, have not been implemented. On the otherhand,
it's nearly 100% ANSI and all of DICE compiles itself (as well as DME,
all of the UUCP1.06 distribution now, and everything else I'm doing).
I.E., it is a real compiler that generates real code.
It has a real nice UNIX CC-like front end (DCC), and since the front end
knows it is loading DICE executables it searches the resident list itself
to find the sub-programs (DCPP, DC1, DAS, DLINK). The end result is that
there is no overhead running the sub-programs if they are resident.
DICE supports residentability (and there are no restrictions on library
calls since amiga.lib is made small-data-model). You can even declare
a huge BSS array that causes BSS data to go over 64KBytes -- as long as
it is the *last* declaration in the *last* module of your code and you
do not use any constant-indexes that would go beyond the small-data 16
bit offset limit. The assembler and/or linker will catch any problems.
The reason this works is because the linker, DLink, guarentees section
ordering and the library code (c.lib) is compiled with different
section names than the default AND the startup module (c.o) declares
these alternate section names before the standard section names, thus
guarenteeing that all library BSS declarations come before any user BSS
declarations.
This also means you only need one c.lib, ... not the 10 billion
versions that come with Lattice and Aztec compilers. Oh, there are a
few cases where you might need a large-data-only model version of
c.lib, but only if you are doing something really esoteric. Also,
there is only one c.o startup module and it handles both the resident
and non-resident case.
Resident code will startup nearly instantaniously because the startup
code does not need to do any 32 bit data-data relocations, ever. The
additional code required to support resident in c.o is miniscule. This
is due to the fact that the compiler, when given the -r option, will
generate special autoinit code *instead* of a normal 32 bit data-data
reference for statically initialized data. I.E. something like this:
short a;
short *b = &a; /* a 32 bit relocation */
(no -r option) (with -r option)
section bss,bss section bss,bss
ds.w 0 ds.w 0
_a ds.b 2 _a ds.b 2
section data,data section data,data
ds.w 0 ds.w 0
_b dc.l _a _b dc.l 0
section autoinit0,code
lea _a(A4),A0
move.l A0,_b(A4)
section text,code section text,code
... ...
All autoinit sections are glued together at link time and called as
a single subroutine from c.o, with a terminating (x.o) module at
the end containing the single RTS. The DCC front end handles all of
this for you.
Autoinit sections also support the automatic openning and closing of
certain system libraries (I only implemented a few but you can
implement more) without the programmer having to lift a finger. E.G. a
library module exists which declares a library base variable. If you
reference that variable in your code but do NOT declare it, the library
code module containing the declaration will be included along with
autoinit code also defined in that module to open the library on
startup and close it on _exit. If you *do* declare the library base
variable then the library module is not included and you have to open
and close the library yourself, so this feature is compatible with code
that does it the normal way.
Oh gee, almost forgot. I do have a special _autoinit keyword which you
can apply to a subroutine that, guess what!, yup! calls that subroutine
from c.o *before* _main(), allowing arbitrary init segments that get
called simply due to their existance at link time and completely
independant from all the rest of your code.... useful when you do not
want the 'user' code to know about the module.
DICE does not have registerized parameters or inline library calls.
Frankly, anybody who appreciates such options also knows that simply
optimizing one or two of his core routines will get better results
anyway and these so called features only make the code less portable
and more unreadable :-).
Sorry, no stack checking option :-(.
DICE will use D0/D1/A0/A1 for register variables whenever a code block
or sub block { } does not contain subroutine calls. This usually
results in DICE being able to substantially reduce the number of
registers required to be saved and restored and to have more registers
available for variables than would otherwise be usable. In many cases
low level subroutines can completely eliminate the MOVEMs or at least
reduce it to MOVEs. I think this is the major reason my code appears
to run faster than Lattice (I don't know about Aztec, haven't compared
those two yet) when running code compilable under both compilers (i.e.
no floating point in the test). DICE also optimizes out LINK/UNLK if A5
is never referenced in the procedure *and* no subroutine calls are made
from the procedure. DAS also optimizes Bxx-to-BRA (up to 20 levels),
and uses short branches when possible, so many levels of loops, gotos,
and/or if()s if()/else's get optimized nicely.
You get source to the C library (written by me), though *not* source to
the DICE binaries. I'm sending DICE to Tad tomorrow. That ought to do
it for the synopsis.
-Matt
--
Matthew Dillon uunet.uu.net!overload!dillon
891 Regal Rd.
Berkeley, Ca. 94708
USA
Technical Details
Message-ID:
<dillon.4040@overload.UUCP>Path:
arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!samsung!uunet!overload!dillonReferences:
<9005290344.AA10362@thunder.LakeheadU.Ca>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!samsung!uunet!overload!dillon From: dillon@overload.UUCP (Matthew Dillon) Newsgroups: comp.sys.amiga.tech Subject: Re: DICE Message-ID: <dillon.4040@overload.UUCP> Date: 31 May 90 00:24:58 GMT References: <9005290344.AA10362@thunder.LakeheadU.Ca> Lines: 135