Commit 751ce3a7 authored by Ken Thompson's avatar Ken Thompson

segmented stacks AND goroutines

SVN=126929
parent ae905980
...@@ -28,7 +28,7 @@ if(newproc == N) { ...@@ -28,7 +28,7 @@ if(newproc == N) {
newproc = nod(ONAME, N, N); newproc = nod(ONAME, N, N);
memset(newproc, 0, sizeof(*newproc)); memset(newproc, 0, sizeof(*newproc));
newproc->op = ONAME; newproc->op = ONAME;
newproc->sym = pkglookup("_newproc", "sys"); newproc->sym = pkglookup("newproc", "sys");
newproc->class = PEXTERN; newproc->class = PEXTERN;
newproc->addable = 1; newproc->addable = 1;
newproc->ullman = 0; newproc->ullman = 0;
...@@ -603,10 +603,12 @@ ginscall(Node *f, int proc) ...@@ -603,10 +603,12 @@ ginscall(Node *f, int proc)
if(proc) { if(proc) {
nodreg(&reg, types[TINT64], D_AX); nodreg(&reg, types[TINT64], D_AX);
gins(ALEAQ, f, &reg); gins(ALEAQ, f, &reg);
nodreg(&reg, types[TINT64], D_BX); gins(APUSHQ, &reg, N);
nodconst(&con, types[TINT32], argsize(f->type)); nodconst(&con, types[TINT32], argsize(f->type));
gins(AMOVL, &con, &reg); gins(APUSHQ, &con, N);
gins(ACALL, N, newproc); gins(ACALL, N, newproc);
gins(APOPQ, N, &reg);
gins(APOPQ, N, &reg);
return; return;
} }
gins(ACALL, N, f); gins(ACALL, N, f);
......
...@@ -572,19 +572,20 @@ dostkoff(void) ...@@ -572,19 +572,20 @@ dostkoff(void)
Sym *symmorestack; Sym *symmorestack;
pmorestack = P; pmorestack = P;
symmorestack = lookup("_morestack", 0); symmorestack = lookup("sys·morestack", 0);
if(symmorestack->type == STEXT) if(symmorestack->type == STEXT)
for(p = firstp; p != P; p = p->link) { for(p = firstp; p != P; p = p->link) {
if(p->as == ATEXT) { if(p->as == ATEXT) {
if(p->from.sym == symmorestack) { if(p->from.sym == symmorestack) {
pmorestack = p; pmorestack = p;
p->from.scale |= NOSPLIT;
break; break;
} }
} }
} }
if(pmorestack == P) if(pmorestack == P)
diag("_morestack not defined"); diag("sys·morestack not defined");
curframe = 0; curframe = 0;
curbecome = 0; curbecome = 0;
...@@ -693,7 +694,7 @@ dostkoff(void) ...@@ -693,7 +694,7 @@ dostkoff(void)
p = appendp(p); p = appendp(p);
p->as = AJHI; p->as = AJHI;
p->to.type = D_BRANCH; p->to.type = D_BRANCH;
p->to.offset = 3; p->to.offset = 4;
q = p; q = p;
p = appendp(p); p = appendp(p);
...@@ -707,6 +708,12 @@ dostkoff(void) ...@@ -707,6 +708,12 @@ dostkoff(void)
p->from.offset = (autoffset+160) & ~7LL; p->from.offset = (autoffset+160) & ~7LL;
p->from.offset |= textarg<<32; p->from.offset |= textarg<<32;
p = appendp(p);
p->as = AMOVQ;
p->from.type = D_AX;
p->to.type = D_INDIR+D_R14;
p->to.offset = 8;
p = appendp(p); p = appendp(p);
p->as = ACALL; p->as = ACALL;
p->to.type = D_BRANCH; p->to.type = D_BRANCH;
......
...@@ -44,6 +44,9 @@ func mapaccess2(hmap *map[any]any, key any) (val any, pres bool); ...@@ -44,6 +44,9 @@ func mapaccess2(hmap *map[any]any, key any) (val any, pres bool);
func mapassign1(hmap *map[any]any, key any, val any); func mapassign1(hmap *map[any]any, key any, val any);
func mapassign2(hmap *map[any]any, key any, val any, pres bool); func mapassign2(hmap *map[any]any, key any, val any, pres bool);
func gosched();
func goexit();
func readfile(string) (string, bool); // read file into string; boolean status func readfile(string) (string, bool); // read file into string; boolean status
func bytestorune(*byte, int32, int32) (int32, int32); // convert bytes to runes func bytestorune(*byte, int32, int32) (int32, int32); // convert bytes to runes
func stringtorune(string, int32, int32) (int32, int32); // convert bytes to runes func stringtorune(string, int32, int32) (int32, int32); // convert bytes to runes
...@@ -93,6 +96,10 @@ export ...@@ -93,6 +96,10 @@ export
mapassign1 mapassign1
mapassign2 mapassign2
// go routines
gosched
goexit
// files // files
readfile readfile
......
...@@ -183,25 +183,35 @@ char* sysimport = ...@@ -183,25 +183,35 @@ char* sysimport =
"type sys._esys_089 (sys._esys_090 sys._esys_091 sys._isys_489)\n" "type sys._esys_089 (sys._esys_090 sys._esys_091 sys._isys_489)\n"
"var !sys.mapassign2 sys._esys_089\n" "var !sys.mapassign2 sys._esys_089\n"
"type sys._esys_095 {}\n" "type sys._esys_095 {}\n"
"type sys._osys_499 {_esys_496 sys.string _esys_497 sys.bool}\n" "type sys._esys_096 {}\n"
"type sys._isys_501 {_esys_498 sys.string}\n"
"type sys._esys_094 (sys._esys_095 sys._osys_499 sys._isys_501)\n"
"var !sys.readfile sys._esys_094\n"
"type sys._esys_097 {}\n" "type sys._esys_097 {}\n"
"type sys._osys_510 {_esys_505 sys.int32 _esys_506 sys.int32}\n" "type sys._esys_094 (sys._esys_095 sys._esys_096 sys._esys_097)\n"
"type sys._esys_098 *sys.uint8\n" "var !sys.gosched sys._esys_094\n"
"type sys._isys_512 {_esys_507 sys._esys_098 _esys_508 sys.int32 _esys_509 sys.int32}\n" "type sys._esys_099 {}\n"
"type sys._esys_096 (sys._esys_097 sys._osys_510 sys._isys_512)\n"
"var !sys.bytestorune sys._esys_096\n"
"type sys._esys_100 {}\n" "type sys._esys_100 {}\n"
"type sys._osys_523 {_esys_518 sys.int32 _esys_519 sys.int32}\n" "type sys._esys_101 {}\n"
"type sys._isys_525 {_esys_520 sys.string _esys_521 sys.int32 _esys_522 sys.int32}\n" "type sys._esys_098 (sys._esys_099 sys._esys_100 sys._esys_101)\n"
"type sys._esys_099 (sys._esys_100 sys._osys_523 sys._isys_525)\n" "var !sys.goexit sys._esys_098\n"
"var !sys.stringtorune sys._esys_099\n"
"type sys._esys_102 {}\n"
"type sys._esys_103 {}\n" "type sys._esys_103 {}\n"
"type sys._isys_532 {_esys_531 sys.int32}\n" "type sys._osys_501 {_esys_498 sys.string _esys_499 sys.bool}\n"
"type sys._esys_101 (sys._esys_102 sys._esys_103 sys._isys_532)\n" "type sys._isys_503 {_esys_500 sys.string}\n"
"var !sys.exit sys._esys_101\n" "type sys._esys_102 (sys._esys_103 sys._osys_501 sys._isys_503)\n"
"var !sys.readfile sys._esys_102\n"
"type sys._esys_105 {}\n"
"type sys._osys_512 {_esys_507 sys.int32 _esys_508 sys.int32}\n"
"type sys._esys_106 *sys.uint8\n"
"type sys._isys_514 {_esys_509 sys._esys_106 _esys_510 sys.int32 _esys_511 sys.int32}\n"
"type sys._esys_104 (sys._esys_105 sys._osys_512 sys._isys_514)\n"
"var !sys.bytestorune sys._esys_104\n"
"type sys._esys_108 {}\n"
"type sys._osys_525 {_esys_520 sys.int32 _esys_521 sys.int32}\n"
"type sys._isys_527 {_esys_522 sys.string _esys_523 sys.int32 _esys_524 sys.int32}\n"
"type sys._esys_107 (sys._esys_108 sys._osys_525 sys._isys_527)\n"
"var !sys.stringtorune sys._esys_107\n"
"type sys._esys_110 {}\n"
"type sys._esys_111 {}\n"
"type sys._isys_534 {_esys_533 sys.int32}\n"
"type sys._esys_109 (sys._esys_110 sys._esys_111 sys._isys_534)\n"
"var !sys.exit sys._esys_109\n"
"))\n" "))\n"
; ;
...@@ -16,206 +16,78 @@ TEXT _rt0_amd64(SB),7,$-8 ...@@ -16,206 +16,78 @@ TEXT _rt0_amd64(SB),7,$-8
// allocate the per-user and per-mach blocks // allocate the per-user and per-mach blocks
LEAQ peruser<>(SB), R15 // dedicated u. register LEAQ m0<>(SB), R14 // dedicated m. register
LEAQ permach<>(SB), R14 // dedicated m. register LEAQ g0(SB), R15 // dedicated g. register
MOVQ R15, 0(R14) // m has pointer to its g0
LEAQ (-4096+104+4*8)(SP), AX // create istack out of the given (operating system) stack
MOVQ AX, 0(R15) // 0(R15) is stack limit (w 104b guard)
MOVL $1024, AX
MOVL AX, 0(SP)
CALL mal(SB)
LEAQ 104(AX), BX
MOVQ BX, 0(R14) // 0(R14) is limit of istack (w 104b guard)
ADDQ 0(SP), AX LEAQ (-1024+104)(SP), AX
LEAQ (-4*8)(AX), BX MOVQ AX, 0(R15) // 0(R15) is stack limit (w 104b guard)
MOVQ BX, 8(R14) // 8(R14) is base of istack (w auto*4) MOVQ SP, 8(R15) // 8(R15) is base
CALL check(SB) CALL check(SB)
// process the arguments
MOVL 16(SP), AX // copy argc MOVL 16(SP), AX // copy argc
MOVL AX, 0(SP) MOVL AX, 0(SP)
MOVQ 24(SP), AX // copy argv MOVQ 24(SP), AX // copy argv
MOVQ AX, 8(SP) MOVQ AX, 8(SP)
CALL args(SB) CALL args(SB)
CALL main·main(SB) // create a new goroutine to start program
MOVQ $0, AX PUSHQ $main·main(SB) // entry
MOVQ AX, 0(SP) // exit status PUSHQ $16 // arg size
CALL sys·exit(SB) CALL sys·newproc(SB)
CALL gom0init(SB)
POPQ AX
POPQ AX
CALL notok(SB) // fault CALL notok(SB) // never returns
RET RET
// TEXT sys·breakpoint(SB),7,$-8
// the calling sequence for a routine that BYTE $0xcc
// needs N bytes stack, A args.
//
// N1 = (N+160 > 4096)? N+160: 0
// A1 = A
//
// if N <= 75
// CMPQ SP, 0(R15)
// JHI 3(PC)
// MOVQ $(N1<<0) | (A1<<32)), AX
// CALL _morestack
//
// if N > 75
// LEAQ (-N-75)(SP), AX
// CMPQ AX, 0(R15)
// JHI 3(PC)
// MOVQ $(N1<<0) | (A1<<32)), AX
// CALL _morestack
//
TEXT _morestack(SB), 7, $0
// save stuff on interrupt stack
MOVQ 8(R14), BX // istack
MOVQ SP, 8(BX) // old SP
MOVQ AX, 16(BX) // magic number
MOVQ 0(R15), AX // old limit
MOVQ AX, 24(BX)
// switch and set up new limit
MOVQ BX, SP
MOVQ 0(R14), AX // istack limit
MOVQ AX, 0(R15)
// allocate a new stack max of request and 4k
MOVL 16(SP), AX // magic number
CMPL AX, $4096
JHI 2(PC)
MOVL $4096, AX
MOVL AX, 0(SP)
CALL mal(SB)
// switch to new stack
MOVQ SP, BX // istack
ADDQ $104, AX // new stack limit
MOVQ AX, 0(R15)
ADDQ 0(SP), AX
LEAQ (-104-4*8)(AX), SP // new SP
MOVQ 8(R15), AX
MOVQ AX, 0(SP) // old base
MOVQ SP, 8(R15) // new base
// copy needed stuff from istack to new stack
MOVQ 16(BX), AX // magic number
MOVQ AX, 16(SP)
MOVQ 24(BX), AX // old limit
MOVQ AX, 24(SP)
MOVQ 8(BX), AX // old SP
MOVQ AX, 8(SP)
// are there parameters
MOVL 20(SP), CX // copy count
CMPL CX, $0
JEQ easy
// copy in
LEAQ 16(AX), SI
SUBQ CX, SP
MOVQ SP, DI
SHRL $3, CX
CLD
REP
MOVSQ
// call the intended
CALL 0(AX)
// copy out
MOVQ SP, SI
MOVQ 8(R15), BX // new base
MOVQ 8(BX), AX // old SP
LEAQ 16(AX), DI
MOVL 20(BX), CX // copy count
SHRL $3, CX
CLD
REP
MOVSQ
// restore old SP and limit
MOVQ 8(R15), SP // new base
MOVQ 24(SP), AX // old limit
MOVQ AX, 0(R15)
MOVQ 0(SP), AX
MOVQ AX, 8(R15) // old base
MOVQ 8(SP), AX // old SP
MOVQ AX, SP
// and return to the call behind mine
ADDQ $8, SP
RET RET
easy: TEXT _morestack(SB), 7, $-8
CALL 0(AX) BYTE $0xcc
// restore old SP and limit
MOVQ 24(SP), AX // old limit
MOVQ AX, 0(R15)
MOVQ 0(SP), AX
MOVQ AX, 8(R15) // old base
MOVQ 8(SP), AX // old SP
MOVQ AX, SP
// and return to the call behind mine
ADDQ $8, SP
RET RET
// marker. must be here; used by traceback() to discover calls to _morestack // marker. must be here; used by traceback() to discover calls to _morestack
TEXT _endmorestack(SB), 7, $-8 TEXT _endmorestack(SB), 7, $-8
RET RET
// call a subroutine in a new coroutine TEXT FLUSH(SB),7,$-8
// argument list is on the stack RET
// addr of fn is in AX
TEXT sys·_newproc(SB), 7, $0
// save stuff on interrupt stack
MOVQ 8(R14), CX // istack
MOVQ AX, 0(CX) // fn pointer
MOVQ BX, 8(CX) // arg size
MOVQ SP, 16(CX) // old SP
MOVQ 0(R15), AX // old limit
MOVQ AX, 24(CX)
// switch and set up new limit
MOVQ CX, SP
MOVQ 0(R14), AX // istack limit
MOVQ AX, 0(R15)
CALL _newproc(SB)
// restore old SP and limit
MOVQ 24(SP), AX // old limit
MOVQ AX, 0(R15)
MOVQ 16(SP), AX // old SP
MOVQ AX, SP
/*
* go-routine
*/
TEXT gogo(SB), 7, $0
MOVQ 8(SP), AX // gobuf
MOVQ 0(AX), SP // restore SP
MOVQ 8(AX), AX
MOVQ AX, 0(SP) // put PC on the stack
MOVL $1, AX // return 1
RET RET
TEXT FLUSH(SB),7,$-8 TEXT gosave(SB), 7, $0
MOVQ 8(SP), AX // gobuf
MOVQ SP, 0(AX) // save SP
MOVQ 0(SP), BX
MOVQ BX, 8(AX) // save PC
MOVL $0, AX // return 0
RET RET
TEXT getu(SB),7,$-8 TEXT setspgoto(SB), 7, $0
MOVQ R15, AX MOVQ 8(SP), AX // SP
MOVQ 16(SP), BX // fn to call
MOVQ 24(SP), CX // fn to return
MOVQ AX, SP
PUSHQ CX
JMP BX
POPQ AX
RET RET
GLOBL permach<>(SB),$64 GLOBL m0<>(SB),$64
GLOBL peruser<>(SB),$64
...@@ -8,22 +8,6 @@ extern int32 debug; ...@@ -8,22 +8,6 @@ extern int32 debug;
static int8 spmark[] = "\xa7\xf1\xd9\x2a\x82\xc8\xd8\xfe"; static int8 spmark[] = "\xa7\xf1\xd9\x2a\x82\xc8\xd8\xfe";
//typedef struct U U;
//struct U {
// uint8* stackguard;
// uint8* stackbase;
// uint8* istackguard;
// uint8* istackbase;
//};
typedef struct Stktop Stktop;
struct Stktop {
uint8* oldbase;
uint8* oldsp;
uint8* magic;
uint8* oldguard;
};
extern void _morestack(); extern void _morestack();
extern void _endmorestack(); extern void _endmorestack();
......
...@@ -4,9 +4,9 @@ ...@@ -4,9 +4,9 @@
#include "runtime.h" #include "runtime.h"
G g0; // idle goroutine
int32 debug = 0; int32 debug = 0;
/*BUG: move traceback code to architecture-dependent runtime */
void void
sys·panicl(int32 lno) sys·panicl(int32 lno)
{ {
...@@ -18,7 +18,7 @@ sys·panicl(int32 lno) ...@@ -18,7 +18,7 @@ sys·panicl(int32 lno)
sys·printpc(&lno); sys·printpc(&lno);
prints("\n"); prints("\n");
sp = (uint8*)&lno; sp = (uint8*)&lno;
traceback(sys·getcallerpc(&lno), sp, getu()); traceback(sys·getcallerpc(&lno), sp, g);
sys·breakpoint(); sys·breakpoint();
sys·exit(2); sys·exit(2);
} }
...@@ -571,20 +571,229 @@ check(void) ...@@ -571,20 +571,229 @@ check(void)
initsig(); initsig();
} }
extern register u; void
uint32 a; sys·goexit(void)
{
//prints("goexit goid=");
//sys·printint(g->goid);
//prints("\n");
g->status = Gdead;
sys·gosched();
}
void void
_newproc(byte* fn, int32 siz, byte* args) sys·newproc(int32 siz, byte* fn, byte* arg0)
{ {
a = u; byte *stk, *sp;
G *newg;
prints("_newproc fn="); //prints("newproc siz=");
sys·printpointer(fn); //sys·printint(siz);
prints("; siz="); //prints(" fn=");
sys·printint(siz); //sys·printpointer(fn);
prints("; args=");
sys·printpointer(args); siz = (siz+7) & ~7;
prints("\n"); if(siz > 1024) {
dump(args, 32); prints("sys·newproc: too many args: ");
sys·printint(siz);
prints("\n");
sys·panicl(123);
}
newg = mal(sizeof(G));
stk = mal(4096);
newg->stackguard = stk+160;
sp = stk + 4096 - 4*8;
newg->stackbase = sp;
sp -= siz;
mcpy(sp, (byte*)&arg0, siz);
sp -= 8;
*(byte**)sp = (byte*)sys·goexit;
sp -= 8; // retpc used by gogo
newg->sched.SP = sp;
newg->sched.PC = fn;
goidgen++;
newg->goid = goidgen;
newg->status = Grunnable;
newg->link = allg;
allg = newg;
//prints(" goid=");
//sys·printint(newg->goid);
//prints("\n");
}
G*
select(void)
{
G *gp, *bestg;
bestg = nil;
for(gp=allg; gp!=nil; gp=gp->link) {
if(gp->status != Grunnable)
continue;
if(bestg == nil || gp->pri < bestg->pri)
bestg = gp;
}
if(bestg != nil)
bestg->pri++;
return bestg;
}
void
gom0init(void)
{
gosave(&m->sched);
sys·gosched();
}
void
sys·gosched(void)
{
G* gp;
if(g != m->g0) {
if(gosave(&g->sched))
return;
g = m->g0;
gogo(&m->sched);
}
gp = select();
if(gp == nil) {
// prints("sched: no more work\n");
sys·exit(0);
}
m->curg = gp;
g = gp;
gogo(&gp->sched);
}
//
// the calling sequence for a routine that
// needs N bytes stack, A args.
//
// N1 = (N+160 > 4096)? N+160: 0
// A1 = A
//
// if N <= 75
// CMPQ SP, 0(R15)
// JHI 4(PC)
// MOVQ $(N1<<0) | (A1<<32)), AX
// MOVQ AX, 0(R14)
// CALL sys·morestack(SB)
//
// if N > 75
// LEAQ (-N-75)(SP), AX
// CMPQ AX, 0(R15)
// JHI 4(PC)
// MOVQ $(N1<<0) | (A1<<32)), AX
// MOVQ AX, 0(R14)
// CALL sys·morestack(SB)
//
int32 debug = 0;
void
morestack2(void)
{
Stktop *top;
uint32 siz2;
byte *sp;
if(debug) prints("morestack2\n");
top = (Stktop*)m->curg->stackbase;
m->curg->stackbase = top->oldbase;
m->curg->stackguard = top->oldguard;
siz2 = (top->magic>>32) & 0xffffLL;
sp = (byte*)top;
if(siz2 > 0) {
siz2 = (siz2+7) & ~7;
sp -= siz2;
mcpy(top->oldsp+16, sp, siz2);
}
m->morestack.SP = top->oldsp+8;
m->morestack.PC = (byte*)(*(uint64*)(top->oldsp+8));
if(debug) prints("morestack2 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);
}
void
morestack1(void)
{
int32 siz1, siz2;
Stktop *top;
byte *stk, *sp;
void (*fn)(void);
siz1 = m->morearg & 0xffffffffLL;
siz2 = (m->morearg>>32) & 0xffffLL;
if(debug) prints("morestack1 siz1=");
if(debug) sys·printint(siz1);
if(debug) prints(" siz2=");
if(debug) sys·printint(siz2);
if(debug) prints(" moresp=");
if(debug) sys·printpointer(m->moresp);
if(debug) prints("\n");
if(siz1 < 4096)
siz1 = 4096;
stk = mal(siz1 + 1024);
stk += 512;
top = (Stktop*)(stk+siz1-sizeof(*top));
top->oldbase = m->curg->stackbase;
top->oldguard = m->curg->stackguard;
top->oldsp = m->moresp;
top->magic = m->morearg;
m->curg->stackbase = (byte*)top;
m->curg->stackguard = stk + 160;
sp = (byte*)top;
if(siz2 > 0) {
siz2 = (siz2+7) & ~7;
sp -= siz2;
mcpy(sp, m->moresp+16, siz2);
}
g = m->curg;
fn = (void(*)(void))(*(uint64*)m->moresp);
if(debug) prints("fn=");
if(debug) sys·printpointer(fn);
if(debug) prints("\n");
setspgoto(sp, fn, morestack2);
*(int32*)345 = 123;
}
void
sys·morestack(uint64 u)
{
while(g == m->g0) {
// very bad news
*(int32*)123 = 123;
}
g = m->g0;
m->moresp = (byte*)(&u-1);
setspgoto(m->sched.SP, morestack1, nil);
*(int32*)234 = 123;
} }
...@@ -60,31 +60,59 @@ struct Map ...@@ -60,31 +60,59 @@ struct Map
int32 unused; int32 unused;
void (*fun[])(void); void (*fun[])(void);
}; };
typedef struct Gobuf Gobuf;
struct Gobuf
{
byte* SP;
byte* PC;
};
typedef struct G G; typedef struct G G;
struct G struct G
{ {
byte* stackguard; // must not move byte* stackguard; // must not move
byte* stackbase; // must not move byte* stackbase; // must not move
G* ufor; // dbl ll of all u Gobuf sched;
G* ubak; G* link;
G* runqfor; // dbl ll of runnable int32 status;
G* runqbak; int32 pri;
int32 goid;
}; };
typedef struct M M; typedef struct M M;
struct M struct M
{ {
byte* istackguard; // must not move G* g0; // g0 w interrupt stack - must not move
byte* istackbase; // must not move uint64 morearg; // arg to morestack - must not move
G* curg; // current running goroutine
Gobuf sched;
Gobuf morestack;
byte* moresp;
int32 siz1;
int32 siz2;
};
typedef struct Stktop Stktop;
struct Stktop {
uint8* oldbase;
uint8* oldsp;
uint64 magic;
uint8* oldguard;
}; };
extern register G* g; // R15 extern register G* g; // R15
extern register M* m; // R14 extern register M* m; // R14
enum
{
// G status
Gidle,
Grunnable,
Gdead,
};
/* /*
* global variables * global variables
*/ */
M* allm; M* allm;
G* allu; G* allg;
G* runq; int32 goidgen;
/* /*
* defined constants * defined constants
...@@ -106,18 +134,21 @@ enum ...@@ -106,18 +134,21 @@ enum
/* /*
* common functions and data * common functions and data
*/ */
int32 strcmp(byte*, byte*); int32 strcmp(byte*, byte*);
int32 findnull(int8*); int32 findnull(int8*);
void dump(byte*, int32); void dump(byte*, int32);
int32 runetochar(byte*, int32); int32 runetochar(byte*, int32);
int32 chartorune(uint32*, byte*); int32 chartorune(uint32*, byte*);
extern string emptystring; extern string emptystring;
extern int32 debug; extern int32 debug;
/* /*
* very low level c-called * very low level c-called
*/ */
int32 gogo(Gobuf*);
int32 gosave(Gobuf*);
void setspgoto(byte*, void(*)(void), void(*)(void));
void FLUSH(void*); void FLUSH(void*);
void* getu(void); void* getu(void);
void throw(int8*); void throw(int8*);
...@@ -126,7 +157,7 @@ void mcpy(byte*, byte*, uint32); ...@@ -126,7 +157,7 @@ void mcpy(byte*, byte*, uint32);
void* mal(uint32); void* mal(uint32);
uint32 cmpstring(string, string); uint32 cmpstring(string, string);
void initsig(void); void initsig(void);
void traceback(uint8 *pc, uint8 *sp, void* up); void traceback(uint8 *pc, uint8 *sp, G* gp);
int32 open(byte*, int32); int32 open(byte*, int32);
int32 read(int32, void*, int32); int32 read(int32, void*, int32);
void close(int32); void close(int32);
...@@ -140,6 +171,8 @@ struct SigTab ...@@ -140,6 +171,8 @@ struct SigTab
/* /*
* low level go -called * low level go -called
*/ */
void sys·goexit(void);
void sys·gosched(void);
void sys·exit(int32); void sys·exit(int32);
void sys·write(int32, void*, int32); void sys·write(int32, void*, int32);
void sys·breakpoint(void); void sys·breakpoint(void);
......
...@@ -71,10 +71,6 @@ TEXT sigtramp(SB),1,$24 ...@@ -71,10 +71,6 @@ TEXT sigtramp(SB),1,$24
CALL sighandler(SB) CALL sighandler(SB)
RET RET
TEXT sys·breakpoint(SB),1,$-8
BYTE $0xcc
RET
TEXT sys·mmap(SB),1,$-8 TEXT sys·mmap(SB),1,$-8
MOVQ 8(SP), DI // arg 1 addr MOVQ 8(SP), DI // arg 1 addr
MOVL 16(SP), SI // arg 2 len MOVL 16(SP), SI // arg 2 len
......
...@@ -65,10 +65,6 @@ TEXT sigtramp(SB),1,$24 ...@@ -65,10 +65,6 @@ TEXT sigtramp(SB),1,$24
CALL sighandler(SB) CALL sighandler(SB)
RET RET
TEXT sys·breakpoint(SB),1,$-8
BYTE $0xcc
RET
TEXT sys·mmap(SB),1,$-8 TEXT sys·mmap(SB),1,$-8
MOVQ 8(SP), DI MOVQ 8(SP), DI
MOVL 16(SP), SI MOVL 16(SP), SI
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment