[M3devel] sparc ta/setjmp/longjmp

Tony Hosking hosking at cs.purdue.edu
Wed Nov 25 16:33:42 CET 2009


      asm("     ta      0x3   ! ST_FLUSH_WINDOWS");
      asm("     retl");
      asm("     mov     %sp,%o0");

The sp returned is that for the *callee* SaveRegsInStack, which includes the space for saved registers.  Your version gives an address in the *caller* frame.

On 24 Nov 2009, at 20:55, Jay K wrote:

>  > No.  The sp back from SaveRegsInStack may capture more state than ADR(xx).
>  
> How so?
> Esp. the 32bit version, which doesn't change the register window?
> I can see how maybe the 64bit one would make the current registers available since it allocates a new window.

Correct:

      asm("     save        %sp,-128,%sp");
      asm("     flushw");
      asm("     ret");
      asm("     restore %sp,2047+128,%o0");

>  Maybe we should just setjmp on all architectures and include the jmpbuf in the stack, by making a function call after it and taking the address of a local in the second function?

That could work.

> And also longjmp on Sparc. Basically very much resemble ProcessLive, but just to set sp and not make the callbacks?
> And endeavor to be sure to not waste time getting the signal mask.

OK.

>  
>  - Jay
> 
>  
> From: hosking at cs.purdue.edu
> Date: Tue, 24 Nov 2009 17:17:51 -0500
> To: jay.krell at cornell.edu
> CC: m3devel at elegosoft.com
> Subject: Re: [M3devel] sparc ta/setjmp/longjmp
> 
> On 24 Nov 2009, at 06:05, Jay K wrote:
> 
> Tony,
>  
> Does this seem correct?
>  
> PROCEDURE SignalHandler (sig: int) =
> VAR
> ...
> old:
>  
> me.sp := SaveRegsInStack();
> IF me.sp = NIL THEN me.sp := ADR(xx) END;
> new:
>  
> SaveRegsInStack(); (* no return value *)
> me.sp := ADR(xx); (* unconditional *)
> 
> No.  The sp back from SaveRegsInStack may capture more state than ADR(xx).
> 
>  
>  
>  
> void ThreadPThread__SaveRegsInStack(void)
> {
> #ifdef M3_REGISTER_WINDOWS
> /* On "register window" architectures, setjmp/longjmp tends
> to flush registers to the stack in a fairly portable not
> too inefficient fashion, and saves us the need for
> gnarly assembly. (ta 3 on Sparc, flushrs on IA64)
> */
> jmp_buf jb;
> if (setjmp(jb) == 0) longjmp(jb, 1);
> #endif
> }
>  
>  
> You know -- was the stack pointer returned by SaveRegsInStack before really better/different than just ADR(xx)?
>  
>  
> Consider:
>  
> #   if defined(__arch64__) || defined(__sparcv9)
>       asm("     save        %sp,-128,%sp");
>       asm("     flushw");
>       asm("     ret");
>       asm("     restore %sp,2047+128,%o0");
> #   else
> asm("     ta      0x3   ! ST_FLUSH_WINDOWS");
>       asm("     retl");
>       asm("     mov     %sp,%o0");
> #   endif
>  
>  
> on 32bit, it just returns the unchanged %sp of its caller.
> On 64bit, I suspect kind of the same thing, though I don't know what the 128 or 2047 are. 2047 is probably some "bias" builtin to the register and 128 I guess is required for flushw??
>  
>  
>  - Jay
> 
> 
> 
> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20091125/10cb8ca4/attachment-0002.html>


More information about the M3devel mailing list