[Coco] Compiler info from an offline conversation...
secure at ytunnelpro.com
secure at ytunnelpro.com
Wed Apr 28 02:48:04 EDT 2004
I recently had an email conversation that started out as an inquiry
concering C compilers for the 6809/6309 but not necessarily targeting
the Coco (i.e. Vectrex, Dragon, etc). The conversation also touched upon
a couple of topics which could apply to a few of the more recent
conversions on this "thank god we're spamless" list so I figured I
would pass along some of the highlights. Keep in mind that most of this
is from a fairly topic specific conversation but I've tried to updated
it in places in order to make it a little more generic. This is only the
first part and will post the rest tomorrow (time for bed :D )
Compilers.....
If you're looking for a 6809 specific C compiler there are several out
there although the code they generate varies in quality as does the
language compliance. Depending on how much effort you want to put into
either modifying existing code to conform to the compiler or working on
an optimization file for peephole optimizers there are several ways to
approach the search for a compiler.
Although you'll find several references for commercial compilers unless
you're a development house targeting a lot of 8bit projects the price
will probably be extremely prohibitive and probably won't be any more
beneficial than starting with a freely available one. Here's a rundown
of some compilers available on for the 6809 (including commercial
ones)....
Small-C: There are several versions of this floating around including
some of the first run updates and modifications. Keep in mind that
Small-C supports only a subset of C and most versions don't support
things such as multiple dereferencing of pointers, bitfields, and
exhibits some problems with switch/case statements. Overall Small-C is a
decent place to start since it's small, widely available, easy to
follow, and can be modified quite easily even if the code it generates
isn't exactly efficient. Most versions of Small-C do not support long
(32bit int) or floats.
Introl-C: This is a commercial compiler and I'm not sure if it's even
available anymore. This one is somewhat pricy. I don't know much about
Introl-C as I've never seen o used it.
BCC: This is a C compiler created by Bruce Evans and is widely available
on the Net. It's also included in several Linux distros and can be
found in most GNU or Linux archive. It generates fairly decent code
although it seems to lack good register tracking/allocation, does not
include a lot of internal optimizations, and has only a handful of bugs.
This is the compiler that I used to do a proof of concept port of the
Micro Emacs distro on my site. After creating compatible screen and
keyboard 'drivers' along with a minimal standard C library
implementation I was able to get Micro Emacs up and running on the CoCo
III.
Micro-C: This is a commercial compiler from Dunfield Development systems.
It generates fairly decent code, includes a slew of tools, and uses a
common code base used in all the 8 bit compilers DDS provides. Prices
range from $100 to $200 which if you consider the original Level II
development system (including the C compiler) ran about $79 or $89 back
in the 80's. Source is not included with a purchase. I've played
around with the 8088 version and 6809 version of the compiler and it
seems to work very well but does not include some features in the C
language.
GCC: There is currently an effort to add a 6809 code generator to GCC.
Right now is looks pretty stable and is an ongoing project. The only
problem eight now is that no distro is available yet meaning you will
need to download GCC, add the 6809 code generator, and compile it. I'm
currently working on getting a Win32 distro put together using Cygwin
though but I'm not sure when it'sll be done. The use of GCC has
several advantages as you have access to front ends for Fortran, C++,
Objective-C, Pascal, Modula, and several others like Cobol. If you have
the time and patience needed to download and compile GCC as it requires
lots of disk space and can take a while to compile on older systems. GCC
Is however one of the more desirable compilers as it supports more than
just C.
SDCC: The Small Device C compiler was designed to specifically target
8bit cpu's with limited registers. Creating a code generator for this
compiler is somewhat involved and very time consuming as it appears a
good amount of code must be implemented to compile for the target
machine. SDCC is a great compiler though and is updated frequently. I
only mention this for completness and don't think I would recomment
using SDCC if you're going to write a significant amout of code for
code generation.
Tiny-C: This compiler only targets x86 but could be modified to generate
6809 assembler. It's a farily decent compiler but requires you write
about 60,000 lines of code for a code generator. This compiler also is
not designed as a cross compiler but it's a good candidate to be one.
LCC: This is a free ANSI-C compiler created by Chris Fraser and David
Hansen. When I first started looking into Compilers for the CoCo some
years back I ran into this little gem. The compiler was described in
"lcc, a Retargetable Compiler for C" a book written by the LCC
Authors. The book is definitely interesting reading. The compiler itself
is implemented in such a way that multiple CPU/Machine targets can be
compiled in withouth hassle allowing the same compiler binary to be used
to compile for multiple targets. The entire code generation part of the
compiler is stored in a "machine description" file and parsed into a C
source file. Other than GCC this is up there in the top three compilers
that have great potential to be used as a 6809 C compiler.
BDS: I know very little about this compiler other than the source code is
available and it generates 8080 assembler. Because it targets 8bit
cpu's it's something to at least investigage.
Watcom-C: I only mention this because the source code is freely available
even though it currently generates x86 code. It could probably be
modified to generate 6809 assembler but i don't think the time
investment would yield comparable results.
Microware C compiler/Flex Compiler: These compilers are generally
considered the defacto standard for the systems they run on. The reason
I mention both compilers at the same time is that the Flex C compiler
looks VERY similar to the Microware compiler. Both operate in two passes
(cpass1, cpass2) where the first pass creates intermedial code (ICODE)
extremely similar to Microwares. As I understand it though Microware was
able to merge cpass1 and cpass2 into a single application but it was
never released. The C code for the Flex compiler is available in the
flex archives. If you need just the compiler let me know and I'll dig
it up for you.
The interesting thing about these two compilers is that *IF* the Flex
compiler is a decendant of the Microware compiler (or predecessor) it
should be able to compile itself AND run on the CoCo III with no
modification. If you need a CoCo hosted compiler THIS is the first and
probably only compiler you should look at as it's the only one that has
the potetial to run on the CoCo *AND* generate decent code while
allowing updates, enhancements, and fixes to any bugs that may be found.
Presently there is no 6809 code generation/back end available for LCC
although there are various implementation which target the 6502 and and
Z80. If you're thinking about using LCC and creating a 6809 code
generator/back end for LCC forget it. LCC was designed for CPU's with
multiple accumulator and multiple index registers. Because of this the
front end code tree generator will vomit during register allocation. The
reason for this is the register allocator (in the front end) gets caught
in a loop when processing large or slightly complex expressions because
the "spills" the contents of the accumulator (ACCD) and loads it with
the new result of another code tree in the expression. The only way
around this is to implement a custom register allocator to deal with the
lack of additional registers. You could of course create a considerable
number of pseudo register operations but that's a SIGNIFICANT
undertaking and is not guaranteed to work.
Although the back end (described in a BURG file and converted to C code)
can be used to implement some extremely tight optimizations It's has
several inherent issues. There hope though. When I last looked into
using LCC for CoCo development I modified one of the non-cpu specific
code generators (the symbolic target) to emit ITCODE files (Intermediate
Text Code) reflecting the code tree the compiler generates while
defining code blocks, etc. This however poses an additional complexity -
an additional parser/compiler needs to be written to parse and then
translate the ITCODE into assembler. This also means that you lost a lot
of the internal optimizations that the BURG implementation provides.
Again, don't fret as the ITCODE parser allows for additional
optimizations desperately needed for targeting 8bit CPU's (such as full
register tracking). Since the ITCODE parser is a seperate entity things
such as code generation and register allocation you do gain some
flexibility.
The method of using ITCODE may be time consuming but can yield extremely
well generated. Once I find the source for my ITCODE parser I'll send
it out to you.
Here are some other notes about compilers:
Most ANSI C compilers generate a certain amount of code that doesn't
make sense when targeting 8bit cpu's. This is generally a preamble
which promotes basic types to be aligned on a sepcific boundry. You
might see code like this:
void function(int param)
{
}
compiles to:
ldd param,s
std param,s
This is to ensure things like the following are taken into account:
void function(char param)
{
}
compiles to:
ldb param+1,s
sex
std param,s
This makes sure that the argument is promoted to signed (or unsigned)
type of size(int) to accomodate promotion of signed/unsigned types.
Peephole optimizers:
Prepare to use a peephole optimizer no matter which compiler you go with.
No matter how hard you tweak the code generation there will almost
always be a need for a peephole optimizer to remove or write code
blocks. This is also beneficial is that some optimizations might be
implemented easier or quicker in a peephole optimizer. Your code
generator might end up doing something like:
a = c;
b = c;
compiles to:
ldd 0,s
std 2,s
ldd 0,s
std 4,s
which can be optimized to:
ldd 0,s
std 2,s
std 4,s
Although redundent loads are often handled by the code generator it's
might easier to implement in a peephole opimizer. In other cases it can
be crucial to handle optimizations within the code generator is it can
implement register usage across expressions including common
subexpression elimination. Compilers like LCC handle constant folding (a
= 2 + 5; compiles to a = 7;)
Also keep in mind that if you are targeting RS-DOS there is no standard
runtime or crt0 lib although the GCC 6809 project does include one which
could easily be used with other compilers.
That's all for now....more to come later.
...Chet...
More information about the Coco
mailing list