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