home *** CD-ROM | disk | FTP | other *** search
-
- compiler/compiler compiler/compiler
- compiler/COMPILER compiler/COMPILER
-
- DICE SYSTEM
-
- Matthew Dillon
- 891 Regal Rd.
- Berkeley, Ca. 94708
- USA
-
- dillon@overload.Berkeley.CA.US
- uunet.uu.net!overload!dillon
-
- BIX: mdillon
-
- COMPILER FEATURES LIST AND ORGANIZATION
-
- NOTE: net distributed releases will not contain
- commodore includes or amiga*.lib
-
- (1) Organization of includes and libraries, default:
-
- DINCLUDE: location of top level includes such as stdio.h
-
- DINCLUDE:Amiga13/ location of 1.3 amiga includes, -1.3 option must
- be used with DCC or set in ENV:DCCOPTS
-
- DINCLUDE:Amiga20/ location of 2.0 amiga includes, -2.0 option must
- be used with DCC or set in ENV:DCCOPTS
-
-
- NOTE !!! Amiga 1.3 and 2.0 includes should be placed in the
- subdirectory dinclude:Amiga13 and dinclude:amiga20, that is,
- dinclude:Amiga13/Exec/*.h, dinclude:Amiga13/graphics/*.h, etc...
-
- DCC references startup and libraries to DLIB:
-
- DLIB:amigas13.lib A small-data model version of the 1.3 AMIGA.LIB
- DLIB:amigas20.lib A small-data model version of the 2.0 AMIGA.LIB
- DLIB:cs.lib The main C library for which you have source code
- DLIB:ms.lib The math library
- DLIB:auto.lib The auto library-open library
- DLIB:c.o The startup module
- DLIB:x.o The terminator module
-
- (2) (removed)
-
-
- (3) DCC generated link lines
-
- If you give DICE the following line (assuming DCCOPTS contains the -1.3
- option):
-
- 1> DCC foo.o -o foo
-
- It will run DLink with the following options:
-
- DLink dlib:c.o foo.o dlib:cs.lib dlib:amigas13.lib dlib:auto.lib dlib:x.o -o foo
-
- DLIB:C.O DICE startup code
- FOO.O your object module(s)
- DLIB:CS.LIB small data model version of c.lib
- DLIB:AMIGAS13.LIB small data model version of commodore amiga.lib for 1.3
- DLIB:AUTO.LIB DICE AUTO.LIB
- DLIB:X.O DICE section terminator code
-
-
- Some explanation is in order. AUTO.LIB catches any references to
- common library base variables when no storage has been declared and
- imports code to automatically open said libraries on startup and
- close them on exit. DICE uses this feature to import code to open
- and close "dos.library" when DOSBase is referenced, and also for
- the floating point libraries.
-
- You, the programmer, can use the feature to simply make arbitrary
- library calls and not have to deal with base variables, openning,
- or closing libraries in your code. To take advantage of the
- feature simply do not declare library base variables or open/close
- the libraries.
-
- X.O is used to supply an RTS at the end of the special autoinit and
- autoexit sections. Any module between C.O and X.O may declare
- these special sections to handle run-time relocations and other
- DICE features, and do so such that when the base of the section is
- JSR'd all the various module's code is sequenced through until the
- RTS in X.O is hit for the sections in question.
-
-
- (4) SMALL DATA AMIGA.LIB
-
- DICE uses a small-data model version of Commodore's AMIGA.LIB to
- allow it to generate residentable executables (-r option to DCC).
- The small data amiga.lib, called AMIGAS13.LIB (note the 's') is
- generated from the large modem amiga.lib with the LIBTOS program.
- (under 2.0 it's AMIGAS20.LIB)
-
- The source to the LIBTOS program is available to allow developers
- using DICE to add new base variables to LIBTOS's search list when
- new operating systems come out without having to wait for my
- update.
-
- WARNING!! Commodore screwed up the var-args entry points in the
- 2.0 amiga.lib, such as CreateNewProcTags(). To ensure that you get
- tags that work properly, you must remake the 2.0 's' library from
- the library source archive after installing updates from commodore.
- The DICE library source overides these var-args tags with ones that
- work.
-
- ----------------------------------------------------------------------
-
- COMPILER FEATURES LIST
-
- (0) ANSI. Pretty much ansi. Please report non-ansism problems. Check
- out the doc/KnownBugs list before reporting a problem.
-
- (1) 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.
-
- (2) LINK/UNLK is removed from low level routines that do not reference
- A5 and do not make any subroutine calls.
-
- (3) MOVEM is converted to MOVE or deleted entirely when possible.
-
- (4) Various obvious optimizations: use of BSET, BCLR, BTST as short
- cuts to logic operations, CMP/TST, etc...
-
- (5) 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.
-
- (6) 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.
-
- (7) 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.
-
- (8) _main() shortcut for extremely low level programs.
-
- REFER TO _MAIN.DOC FOR INFORMATION ON USING THE _main()
- ENTRY POINT INSTEAD OF main().
-
- (9) 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.
-
- (10) 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.
-
- (11) 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
-
-
- --------------------------------------------------------------------------
- GOALS
-
- In writing DICE my goals are as follows:
-
- - reasonably fast compilation. Modular executables for ease of use,
- reliability, and testability.
-
- - concentrate more on reliability and less on optimizations. Remember that
- this is only the third major distribution of DICE, I expect some bugs
- to show up. I expect to become more reliable than the two other
- commercial C compilers in the Amiga market within a year.
-
- - but do not forget optimizations... put in relatively easy to implement
- optimizations that do not destroy the reliability of DICE. DICE does
- no common sub-expression or loop unrolling optimizations, but does do
- relatively smart register allocation and multi-level history to
- propogate conditional expressions.
-
- - provide comprehensive support of the Amiga, especially for new
- versions of the OS that come out. DICE fully supports 1.3 and 2.0
- with an easy extension mechanism to allow development on several
- OS versions / betas simultaniously.
-
- - I have always torn my hair out at not being able to easily fix bugs in
- the support libraries for commercial compilers. DICE includes full
- source for its support libraries (c.lib, m.lib, auto.lib) and a means
- to remake the library. DICE also includes full source to some of
- its own utilities, namely LIBTOS and the DCC frontend which are the
- most likely candidates for programmer hair loss.
-
- While you may NOT distribute any source code to non-registered users,
- you can fix bugs you find without having to wait for a new release,
- or add your own features to programs like DCC.
-
- ------------------------------------------------------------------------
- COMMENTS
-
- Registerized parameteres are now implemented. The implementation
- turned out to be not all that complex. However, you cannot as yet
- specify WHICH registers parameters are to be placed for a call.
- Refer to the -mRR option in DCC.DOC
-
- Inline library calls are not implemented. Inline library calls are
- actually useful and when properly implemented increase efficiency to
- low level calls such as AddHead() and GetMsg(). Other calls such as
- Move() and Draw() do not increase noticably in efficiency. #pragma's
- must be used to define inline calls and this makes the compiler
- enviroment less portable. Lattice made a big mistake *requiring* the
- use of inline library calls with residentable programs. My solution
- was to write a program to convert AMIGA**.LIB into a small-data version
- of same called AMIGAS**.LIB.
-
- DICE still uses tags for library calls, but fully registerized tags are
- now available to registered users which significantly reduces library
- call overhead to the point where it's only a few cycles slower than a
- SAS/C inline call, and without the hassle.
-
- Similarly, I have not implemented prototype and amiga-library function
- array support in the compiler or linker but instead have provided
- separate programs to aid in this. While less automated than SAS/C,
- this support is MUCH more portable and, in my opinion, much cleaner, as
- well as more easily maintained.
-
- In general, I refuse to implement a thousand nearly useless features
- that will only introduce more bugs into the compiler.
-
- ------------------------------------------------------------------------
- COMPATIBILITY
-
- ANSI C
-
- With structural returns and auto-aggregate is implemented, DICE is now
- 95% ANSI compliant. Known differences are described in the KNOWNBUGS
- document.
-
- I spent a great deal of time ensuring that STDIO routines run
- relatively fast. I decided to write nearly all of the support library
- in C instead of falling back to optimized assembly to keep the system
- uniform and portable. One does not notice much of a difference between
- the C strcpy() and an assembly strcpy() relative to the run time of
- their program.
-
- AMIGA
-
- As said in feature (7), if you wish your program to be runnable from
- the workbench you must supply a wbmain() entry point. If you do not
- then running the program from the workbench will result in its
- immediate termination (e.g. nothing happens). On return from wbmain()
- or exit() the workbench message is automatically ReplyMsg()d by the
- exit code.
-
- DICE separates workbench startup and puts it in the hands of the user
- to simplify the user's code. Since there are two entry points,
- main() for CLI run programs and wbmain() for WORKBENCH-run programs,
- the programmer can more easily modularize his code.
-
- The Registered release of DICE supports the __near, __far, and __chip
- keywords.
-
- UNBUFFERED CONSOLE IO
-
- You may set a console to RAW mode using the setbuf() and setvbuf() calls.
- You may set a console back to COOKED mode using the same calls.
-
- ------------------------------------------------------------------------
-
- Your first program
-
- 1> cd examples
- 1> dcc hello.c -o ram:hello
- 1> ram:hello
- hello world
- 1>
-
- Your first residentable program
-
- 1> cd examples
- 1> dcc hello.c -o ram:hello -r
- 1> ram:hello
- hello world
- 1> resident ram:hello
- 1> hello ; instantanious execution
- hello world
- 1>
-
- * NOTE, a common problem is that users have removed various floating
- point libraries from LIBS: and this may prevent DC1 from running. Make
- sure you have the full complement of floating point libraries in LIBS:
-
- Another common problem is related to your PATH... if DCC is unable to
- run one of the subprograms (DCPP, DC1, DAS, and DLINK) you may not have
- DCC:BIN in your path. ARP is known to screw things up in this regard
- and if you are running ARP try de-installing it to see if that was the
- problem. You cannot use the ARP resident command (ARES) with DICE
- executables.
-
-
-