home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.arch      Apparently more than just beeps & boops      131,241 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 130,388 of 131,241   
   MitchAlsup to All   
   Re: Tonights Tradeoff - NaN boxed precis   
   28 Nov 25 20:05:00   
   
   From: user5857@newsgrouper.org.invalid   
      
   anton@mips.complang.tuwien.ac.at (Anton Ertl) posted:   
      
   > MitchAlsup  writes:   
   > >   
   > >scott@slp53.sl.home (Scott Lurndal) posted:   
   > >   
   > >> MitchAlsup  writes:   
   > >> >My 66000 ENTER and EXIT instruction use SP == R31 implicitly. But,   
   > >> >instead of giving it a number of registers, there is a start register   
   > >> >and a stop register, so 1-to-32 regsiters can be saved/restored. The   
   > >> >immediate contains how much stack space to allocate/deallocate.   
   > >>   
   > >> That seems both confining for the compiler designers and less   
   > >> useful than the VAX-11 register mask stored in the instruction stream   
   > >> at the function entry point(s).   
   > >   
   > >We, and by that I mean Brian, have not found that so. In the early stages   
   > >we did see a bit of that, and then Brian found a way to allocate registers   
   > >from R31-down-to-R16 that fit the ENTER/EXIT model and we find essentially   
   > >nothing (that is no more instructions in the stream than necessary).   
   > >   
   > >Part of the distinction is::   
   > >a) how arguments/results are passed to/from subroutines.   
   > >b) having a minimum of 7-temporary registers at entry point.   
   > >c) how the stack frame is designed/allocated wrt:   
   > >   1) my  arguments and my  results,   
   > >   2) his arguments and his results,   
   > >   3) varargs,   
   > >   4) dynamic arrays on stack,   
   > >   5) stack frame allocation at ENTER,   
   > >d) freedom to use R30 as FP or as joe-random-register.   
   > >   
   > >These were all co-designed together, after much of the instruction   
   > >emission logic was sorted out.   
   >   
   > What is "my" and "his"?   
      
   My arguments are the arguments to me (this subroutine)   
   His arguments are the arguments to subroutines I call   
      
   > >Consider this as a VAX CALL model except that the mask was replaced by   
   > >a list of registers, which were then packed towards R31 instead of a bit   
   > >vector.   
   >   
   > Do you need both a start and a stop register?   
      
   Consider:   
        ENTER   R19,R31,#constant   
   versus   
        ENTER   R19,R0,#constant   
      
   The former saves R19-through-R31 and leave the return address in R0   
      
   The later saves R19-through-R0 leaving the return address on the stack.   
      
   This should illustrate that the stopping register is compiler chosen.   
   It is obvious that the starting point should be compiler chosen.   
   Thus, start and stop are independent.   
      
   Now Consider:   
        ENTER   R19,R9,#constant   
      
   Not only are R19-R0 saved on the stack, R1-R9 are saved on the stack   
   immediately preceding the memory based arguments, thus varargs only   
   changes the stop register in ENTER; and this makes a linear vector   
   of arguments for valist.   
      
   > As far as I understand, ENTER is at the entry point of the callee, and   
   > EXIT is before the return or tail call; actually, the tail call case   
   > answers my question above:   
   >   
   > If the tail-caller has m callee-saved registers and the tail-callee   
   > has n callee-saved registers, then   
   >   
   > if m>n, generate an EXIT that restores the m-n registers;   
   > if m Generate a jump to behind the ENTER instruction of the callee.   
      
   The above sounds complicated enough to simply avoid the tail-call   
   optimization it the arguments lists are not similar enough.   
      
   > That is, assuming that the tail-callee is in the same compilation unit   
   > as the tail-caller; otherwise the tail-caller needs to do a full EXIT   
   > and then jump to the normal entry point of the tail-callee, which does   
   > a full ENTER.   
   >   
   > And in these ENTERs and EXITs, you don't end (or start) at the same   
   > point as in the regular ENTERs and EXITs.   
   >   
   > And yes, for saving the callee-saved registers I don't see a need for   
   > a mask.  For caller-saved registers, it's different.  Consider:   
   >   
   > long foo(...)   
   > {   
   >   long x = ...;   
   >   long y = ...;   
   >   long z = ...;   
   >   if (...) {   
   >     bar(...);   
   >     x = ...;   
   >   } else if (...){   
   >     baz(...);   
   >     y = ...;   
   >   } else {   
   >     bla(...);   
   >     z = ...;   
   >   }   
   >   return x+y+z;   
   > }   
   >   
   > Here one could put x, y, and z in callee-saved registers (and use ENTER   
   > and EXIT for them), but that would need to save and later restore   
   > three registers on every path through foo().   
   >   
   > Or one could put it in caller-saved registers and save only two   
   > registers on every path through foo().  Then one needs to save y and z   
   > around the call to bar(), x and z around the call to baz(), and x and   
   > y around the call to bla().  For any register allocation, in one of   
   > the cases the registers to be saved are not contiguous.  So if one   
   > would use a save-multiple or load-multiple instruction for that, a   
   > mask would be needed.   
      
   There is a delicate balance between callee-save and caller-save   
   registers. In many situations caller-save is better (counting   
   instructions) but callee-save is better (counting cycles--mostly   
   due to second order cache effects).   
      
   > - anton   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca