using (ugh! yetch!) assembler

David Collier-Brown daveb at geac.UUCP
Fri Aug 5 22:46:14 AEST 1988


>From article <856 at l.cc.purdue.edu>, by cik at l.cc.purdue.edu (Herman Rubin):
> But what do you recommend if your languages (C, FORTRAN, etc.) are
> incapable of doing even a remotely reasonable job with the program?

>...   Now many (all that I have
> seen, but I have been told that there are ones which do not have this problem)
> C compilers will not allow asm instructions to use the compiler's knowledge of
> which registers are assigned to which variables.

  There are two problems here: expressive power of the language and
quality of the compiler/embedded-assembler interface.

Problem 1: Language.
  Get a better language.  No smileys here, its a serious suggestion.
C may be my favorite language, but I won't claim it is either modern
or consistently well-implemented.  Use FORTRAN for numerical
problems if C gets in the way, C for structure-shuffling if FORTRAN
gets in the way.  Use Ada or C++ if the non-extensibility of either
gets in the way.  

Problem 2: Compilers.
  Get a good one, for whatever language you buy.  Make sure it will
use the machine's standard[1] call interface if one exists, so you can
mix languages.  

   An anecdote: I once used an Ada[2] cross-compiler, back when Ada
was **real** new and implementations tended to be weak.  When I had
to generate an in-line trap, I discovered I could state it all in
the HLL.  One declaration of a bit pattern (which was the
instruction), one package definition to define the interface to it
and umpty-dozen pragmas to say 
	put it in-line
	parameter A must be in register An and An+1
	parameter B must be in register R1
   Net result? It generated almost "perfect" code for the trap,
without any register-moves or call-return linkages.  This is
extensible to modeling almost any machine instruction[3], and one can
always re-write the package to turn it into a different instruction
(or sequence of instructions) if you have to port it.


  --OR--
  You can try to invalidate the problem, and make the compiler
generate optimal code.  Yes, I said MAKE.

  Another anecdote: last year, I had to speed up a critical inner
loop in a very large system written in Pascal.  The compiler **would
not** accept a declaration for the construct that was needed (a
pointer to an array greater than its normal maximum size).  It was
initially done by allocating the array in the non-pascal startup
code and using inline assembler to access it.  It was ***slow***.
  When I looked at the code generated, inlining had only saved me
the call-return instruction pair, not the required register/stack
setup for the call.
  So I wrote out the addressing expression in Pascal, as arithmetic.
The code it generate was one instruction "poorer" than the optimum,
because it moved the result from the general registers to the
address registers at the end.  This was 6 instructions better than
the inline assembler, and 8 better than out-of line instructions.
(The move occurred as a result of my using an explicit union: if the
language understood casts, it might have disappeared too).
  Result?  We got our speedup, even though Pascal "knew" it wasn't
supposed to be that helpful.

  So don't dispair, you can get out of almost any problem in
Confuser Science: you just have to go back to first principles and
attack the meta-problem.

--dave (no cute statement today) c-b
[1] Including de-facto ones, if the hardware one is yucky...
[2] Ada is a trademark of the U.S. Gov't (Ada Joint Project Office)
[3] This is generally a super-non-portable idea, though.
-- 
 David Collier-Brown.  |{yunexus,utgpu}!geac!daveb
 Geac Computers Ltd.,  |  Computer science loses its
 350 Steelcase Road,   |  memory, if not its mind,
 Markham, Ontario.     |  every six months.



More information about the Comp.lang.c mailing list