[net.micro.68k] asm construct in PCC's: workaround

gnu@hoptoad.uucp (John Gilmore) (04/21/86)

In article <581@mtxinu.UUCP>, ed@mtxinu.UUCP (Ed Gould) writes:
>                             ...there is a bug in the 4.2BSD compiler,
> and possibly other PCC derivatives as well.  I don't remember the
> nature of the bug in any detail, but the workaround is to place
> a null statement (extra semicolon) before the asm():
> 
> 	;asm("whatever");

The bug occurs when the asm() is preceded by an if-statement, e.g.:

	if (flag)
		do_something();
	asm("now do this");

PCC injects the asm() into the output before it recognizes that the if
statement is done, so the asm() is effectively placed inside the if
statement.  Having it scan a null statement before the asm() works.

Now for a bit of soapboxing:  I had to maintain a large piece of code
containing asm()'s (the Sun boot proms, which developed out of code
written at Stanford by Luis Trabb-Pardo and others).  Eventually I gave
up; there were too many dependencies on the compiler: where it
allocated variables, what the peephole optimizer would accept and
understand, etc.  Every time Richard Tuck improved the Sun C compiler,
my code would break in obscure ways.  I always ended up compiling it
with both compilers and diff-ing the .s files and reading the diffs.
For each compiler release over 3-1/2 years.  While this was a great
check on the generated code and helped Richard avoid bugs, it took a
lot of time.

I finally rewrote all the asm() parts so the assembler code
was in separate foo.s files, my life became easier, my code became
more maintainable, I found a good lover, my ship came in, and my
soapboxing is over.
-- 
John Gilmore  {sun,ptsfa,lll-crg,ihnp4}!hoptoad!gnu   jgilmore@lll-crg.arpa
			     Post no bills.

earle@smeagol.UUCP (Greg Earle) (04/23/86)

In article <716@hoptoad.uucp>, gnu@hoptoad.uucp (John Gilmore) writes:
> Now for a bit of soapboxing:  I had to maintain a large piece of code
> containing asm()'s (the Sun boot proms, which developed out of code
> written at Stanford by Luis Trabb-Pardo and others).  Eventually I gave
> up; there were too many dependencies on the compiler: where it
> allocated variables, what the peephole optimizer would accept and
> understand, etc.  Every time Richard Tuck improved the Sun C compiler,
> my code would break in obscure ways.  I always ended up compiling it
> with both compilers and diff-ing the .s files and reading the diffs.
> For each compiler release over 3-1/2 years.  While this was a great
> check on the generated code and helped Richard avoid bugs, it took a
> lot of time.

Amen!  To this I'll add our own experience ...
We use Suns for development of code that eventually runs on Heurikon SBC's
(as well as on the Sun).  We decided to replace the Heurikon Boot PROMs
with our own design.  The fun came when using asm(" ") statements in things
like interrupt handlers, e.g., remove the 'MORE CODE ...' line in this
example (if you have a Sun), and create .o files using -c and then -O -c:
----------------------------------------------------------------------------
asm("                                                           \n\
        SAVMASK = 0xFFFE                                        \n\
        RESMASK = 0x7FFF                                        \n\
                                                                \n\
        .text                                                   \n\
                                                                \n\
        .globl  _address_error_interrupt                        \n\
                                                                \n\
_address_error_interrupt:                                       \n\
                                                                \n\
        moveml  #SAVMASK,a7@-           | save all registers    \n\
                                                                \n\
        movl    usp,a0                  | push user stack ptr   \n\
                                        | can't directly push   \n\
                                        | the USP - see MOVEC   \n\
        movl    a0,a7@-                                         \n\
                                                                \n\
        movl    sp,a7@-                 | push sys stack ptr    \n\

| [ MORE CODE HERE DELETED ]
                                                                ");

main()
{
	printf("Hello, world!\n");
}
---------------------------------------------------------------------------
(Obviously, in the actual file there was no main function)

Now disassemble the optimized and non-optimized object files.
Our Suns' optimizer decided it was hungry, so it ate the 

        movl    usp,a0                  | push user stack ptr   \n\

line, whole!!!  The resulting object code just has the A0 push
instruction left.

Our problem was, the default for all the compiles in the Make (including
*many* files with no "asm" statements in them) was to optimize via -O, in 
order to try and reduce the size of the resulting object files before
squeezing the code into the PROMs ...
Needless to say, this caused some very interesting crashes when the new
PROMs were burned and installed, and it was *very hard* to find the cause.

Added to the fun was the fact that the Sun compiler changed between Sun's
1.x and 2.0 releases, and it no longer supported merely \ ing the newlines
in order to get many statements into one asm("...").  No documentation of
this change was to be found, and I discovered the solution (\n\, see above)
by Good 'Ol Trial And Error ...
-- 
	Greg Earle		UUCP: sdcrdcf!smeagol!earle
	JPL			ARPA: ia-sun2!smeagol!earle@csvax.caltech.edu

If our behavior is strict, we do not need fun!