[M3devel] sparc ta/setjmp/longjmp
Jay K
jay.krell at cornell.edu
Thu Nov 26 02:57:09 CET 2009
There's no difference. Is there?
call is "jump and link", no change to sp. Right?
No parameters are passed to the function, so no pushes (if the calling sequence even would).
Notice that if there is a difference, calling sem_post will wipe it out anyway.
How about an implementation that calls setjmp on all platforms, longjmp right away if there are register windows, and then uses the address of the jmpbuf as the stack pointer?
- Jay
From: hosking at cs.purdue.edu
Date: Wed, 25 Nov 2009 10:33:42 -0500
To: jay.krell at cornell.edu
CC: m3devel at elegosoft.com
Subject: Re: [M3devel] sparc ta/setjmp/longjmp
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/20091126/1a1799bc/attachment-0002.html>
More information about the M3devel
mailing list