[comp.realtime] 68HC11 Compiler Evaluation

elliott@optilink.UUCP (Paul Elliott x225) (09/28/89)

Motorola 68HC11 controllers, oriented towards real-time operation.  In it,
I mentioned that I had participated in an evaluation of several c compilers
for the 68HC11.  A few of you have requested more info on this, so I am posting
a summary of our experience at Optilink.

Please note that I am not using any of these products here currently; I have
been too busy designing T1 hardware.  My boards do have the 68HC11 on them,
so I remain somewhat familiar with the trials and tribulations of the
firmware engineers with respect to these compilers (and emulators).  Also,
this evaluation took place about a year ago, so the problems/features I mention
may have changed dramatically.  Of course, these recollections of mine are
subject to human error, so obviously can not be attributed to Optilink Corp,
since the last time I checked Optilink was not human, and therefore cannot make
errors ;-).  

I strenuously recommend that, if it is important to you, you perform an 
independent evaluation.  The tools have been evolving, and new ones have been 
introduced.  A followup, if you discover anything interesting, would be 
appreciated.

Before choosing the 68HC11, we evaluated several assemblers, c compilers, and
emulators (a micro isn't much use if the development tools are lousy or
non-existent).  We selected four compiler vendors, and submitted a source-code
file to each; the code consisting of a few thousand lines of generic c, and
some "typical" interrupt service routine hardware interface code.  Each vendor
returned the compiled output for our inspection.  We evaluated the compiler
output for code size, speed, and general quality, the last being admittedly
subjective.

The emulator vendors were:
********* Pentica ********* 
This emulator is somewhat expensive, but very flexible.  We are
currently using these.

********* Huntsville Microsystems ********* 
About half the price of the Pentica, but more limited.  For our application,
it has a fatal flaw in that it will not properly support the "special
bootstrap mode" of the 68HC11.

The compiler vendors were:
********* Intermetrics: *********
I've misplaced the assembly output, but recall that this compiler had a 
problem with the evaluation of expressions that could be "short circuited".
For example, the expression:

    if (var1 && var2 && var3)
	do_something();

    next_function();

would compile to something like this (comments mine):
    ldaa var1
    beq L1	;if (!var1)

    ldaa var2
    beq L2	;if (!var2)

    ldaa var3
    beq L3	;if (!var3)

;expression evaluated TRUE, proceed
    jsr do_something

L1: bra L2	;note the chained exit branches
L2: bra L3
L3: bra L4

L4: jsr next_function

This is not an error, but produces larger, slower code than necessary.  

********* American Automation: ********* 
This compiler had one serious problem, when evaluated for real-time use;
the use of subroutines for (almost?) all byte expression evaluations (by this 
I mean (var1), (!var1), (var1 != FOO), (var1 <= var2), (0x01 == 0xff), etc.).
The overhead of constantly calling these evaluation subroutines could be fatal
in time-critical code.  All the other compilers we evaluated managed to
use the bge, ble, beq, bne opcodes directly to perform these tests for bytes.
For example, the Introl compiler uses inline tests for 8-bit and 16-bit tests,
and calls comparison subroutines for doubles (32-bits) (which seems a pretty
good tradeoff).  A simple example of the American Automation compiler output 
follows:

Source code:
    if (!Mode.SendingMsg)
	InterruptCtlImage &= ~TICK125;

yields the assembly (comments are mine):
    ldab Mode?+4    ;4 is the SendingMsg offset into the Mode structure
    jsr ?cn	    ;?cn is the "compare not" subroutine
    beq ?105	    ;testing the result of the comparison subroutine

    ldab InterruptCtlImage?
    andb #low 65533
    stab InterruptCtlImage?

105:

The American Automation also had problems with cleanup of post-evaluation
branches to branches to branches.


********* Archimedes: ********* 
This compiler generated clean code for our benchmarks.

********* Introl: ********* 
This compiler generated clean code.  It did have a habit of performing
unnessesary tstb operations where the flags were already set by a load or 
other operation.  We did not dock too many points for this minor flaw.

After we examined the compiler outputs, we decided that either the Archemedes
or the Introl compilers would be adequate from a code standpoint.  To decide
between these two, we noted that the Introl compiler was supported by both
of the emulators we were considering, at least as far as symbol table support
went.  The Pentica emulator software was going to provide source-level 
debugging for the Introl compiler "any day now", so that was another point in 
it's favor.  To the best of my knowledge, we still don't have source-level
debugging, however.  Introl also provides an assembler that was deemed useable,
and provided these for both PCDOS and UN*X (we use Suns, PCs, and Macs here).

Our final decision was to use the Pentica emulator, and the Introl compiler and
assembler.  This combination, while not perfect, has proven very useable.  Note
that the best of these compilers do not produce code equal to hand-assembly.
We are using assembly in all time-critical areas.  Do not expect the compilers
to perform any but the most rudimentary optimization.

I hope this has been of some use,

Paul


-- 
Paul M. Elliott      Optilink Corporation     (707) 795-9444
         {pyramid,pixar,tekbspa}!optilink!elliott
"I used to think I was indecisive, but now I'm not so sure."