MOVL $0, AX // return 0
RET
+/*
+ * support for morestack
+ */
+
+// return point when leaving new stack. save AX, jmp to oldstack to switch back
+TEXT retfromnewstack(SB), 7, $0
+ MOVQ AX, 16(R14) // save AX in m->cret
+ MOVQ $oldstack(SB), AX
+ JMP AX
+
+// gogo, returning 2nd arg instead of 1
+TEXT gogoret(SB), 7, $0
+ MOVQ 16(SP), AX // return 2nd arg
+ MOVQ 8(SP), BX // gobuf
+ MOVQ 0(BX), SP // restore SP
+ MOVQ 8(BX), BX
+ MOVQ BX, 0(SP) // put PC on the stack
+ RET
+
TEXT setspgoto(SB), 7, $0
MOVQ 8(SP), AX // SP
MOVQ 16(SP), BX // fn to call
static int8 spmark[] = "\xa7\xf1\xd9\x2a\x82\xc8\xd8\xfe";
-extern void morestack2();
-
void
traceback(uint8 *pc, uint8 *sp, void* r15)
{
name = "panic";
for(;;){
callpc = pc;
- if((uint8*)morestack2 == pc) {
- // call site is morestack2(); pop to earlier stack block to get true caller
+ if((uint8*)retfromnewstack == pc) {
+ // call site is retfromnewstack(); pop to earlier stack block to get true caller
stktop = (Stktop*)g.stackbase;
g.stackbase = stktop->oldbase;
g.stackguard = stktop->oldguard;
// CALL sys·morestack(SB)
//
-int32 debug = 0;
-
void
-morestack2(void)
+oldstack(void)
{
Stktop *top;
uint32 siz2;
byte *sp;
-if(debug) prints("morestack2\n");
+if(debug) prints("oldstack m->cret = ");
+if(debug) sys·printpointer((void*)m->cret);
+if(debug) prints("\n");
top = (Stktop*)m->curg->stackbase;
m->morestack.SP = top->oldsp+8;
m->morestack.PC = (byte*)(*(uint64*)(top->oldsp+8));
-if(debug) prints("morestack2 sp=");
+if(debug) prints("oldstack sp=");
if(debug) sys·printpointer(m->morestack.SP);
if(debug) prints(" pc=");
if(debug) sys·printpointer(m->morestack.PC);
if(debug) prints("\n");
- gogo(&m->morestack);
+ gogoret(&m->morestack, m->cret);
}
void
-morestack1(void)
+newstack(void)
{
int32 siz1, siz2;
Stktop *top;
siz1 = m->morearg & 0xffffffffLL;
siz2 = (m->morearg>>32) & 0xffffLL;
-if(debug) prints("morestack1 siz1=");
+if(debug) prints("newstack siz1=");
if(debug) sys·printint(siz1);
if(debug) prints(" siz2=");
if(debug) sys·printint(siz2);
if(debug) prints("fn=");
if(debug) sys·printpointer(fn);
if(debug) prints("\n");
- setspgoto(sp, fn, morestack2);
+ setspgoto(sp, fn, retfromnewstack);
*(int32*)345 = 123;
}
g = m->g0;
m->moresp = (byte*)(&u-1);
- setspgoto(m->sched.SP, morestack1, nil);
+ setspgoto(m->sched.SP, newstack, nil);
*(int32*)234 = 123;
}
{
G* g0; // g0 w interrupt stack - must not move
uint64 morearg; // arg to morestack - must not move
+ uint64 cret; // return value from C - must not move
G* curg; // current running goroutine
Gobuf sched;
Gobuf morestack;
*/
int32 gogo(Gobuf*);
int32 gosave(Gobuf*);
+int32 gogoret(Gobuf*, uint64);
+void retfromnewstack(void);
void setspgoto(byte*, void(*)(void), void(*)(void));
void FLUSH(void*);
void* getu(void);