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."