[comp.os.xinu] sun c compiler bug

narten@PURDUE.EDU (Thomas Narten) (12/17/87)

>> /* macro to store the SR onto the stack and disable interrupts */
>> #define disable()	asm("movw sr, sp@-"); asm("movw #0x2700, sr");
>> 
>> /* macro to restore previous SR from the stack */
>> #define restore()	asm("movw sp@+, sr");
>> 
Thinking about it some more, disable() restore() are done all wrong.
They should both be procedures that call routines in locore.s to do
the actual work.

Reasons:

1) the semantics of disable() (or disable(ps) in the lsi version) are
not the same as for procedure calls. This makes it more difficult to
understand.

2) the old value of the PS is not saved in a variable the user
declares (in the sun version).

3) the syntax/semantics of disable/restore are different in the lsi
and sun versions (ouch).

4) using assembly escapes in the middle of C code is a hack, and often
causes funny interactions with the C compiler especially when the
optimizer is used. (I say this not for the sun version, I ran into
problems with the 8086 C compiler).

5) The lsi  scheme requires that the user declare the ps variable,
but I seem to remember that if you forget to declare it, the error
message is either non existant (in which case the generated code  is
wrong) or very obscure. This stems from the "hacky" nature of the
disable implementation of the 11 compiler. 

6) The overhead for a procedure call is not that significant. In fact,
Sun versions of Unix use procedure calls for enabling/disabling
interrupts.

7) If you are worried about overhead, the following trick can be used:

Run the first pass of the compiler that generates assembly code and
pipe the output through a sed script "inline". Inline substitutes
strings (using pattern matching) of the form "call disable" with the
assembly language equivalent that performs that task. The beauty of
this scheme is that all arguments are now in the form of assembly
language addresses. For instance the following sun code:

bomb()
{
    int ps;
    ps = disable();
    globalvar = 1;
    restore(ps);
}

assembles into:
_bomb:
|#PROLOGUE# 0
	link	a6,#-4
|#PROLOGUE# 1
	jbsr	_disable
	movl	d0,a6@(-4)
	moveq	#1,d1
	movl	d1,_globalvar
	movl	d0,sp@-
	jbsr	_restore
	addqw	#4,sp
	unlk	a6
	rts

The sed script would change:
    jbsr _disable
to:
    movw sr, d0
    movw #0x2700, sr

and
    movl d0,sp@-
    jbsr _restore
would change to:
    movw sp@+, sr

    This trick works on any compiler, without modifying the compiler
at all.

Thomas