Commit 1f6828bc authored by Ken Thompson's avatar Ken Thompson

segmented stack

SVN=125151
parent f977e251
...@@ -52,8 +52,8 @@ ...@@ -52,8 +52,8 @@
%token <dval> LFCONST %token <dval> LFCONST
%token <sval> LSCONST LSP %token <sval> LSCONST LSP
%token <sym> LNAME LLAB LVAR %token <sym> LNAME LLAB LVAR
%type <lval> con expr pointer offset %type <lval> con con3 expr pointer offset
%type <gen> mem imm reg nam rel rem rim rom omem nmem %type <gen> mem imm imm3 reg nam rel rem rim rom omem nmem
%type <gen2> nonnon nonrel nonrem rimnon rimrem remrim spec10 %type <gen2> nonnon nonrel nonrem rimnon rimrem remrim spec10
%type <gen2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 %type <gen2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9
%% %%
...@@ -177,12 +177,12 @@ spec1: /* DATA */ ...@@ -177,12 +177,12 @@ spec1: /* DATA */
} }
spec2: /* TEXT */ spec2: /* TEXT */
mem ',' imm mem ',' imm3
{ {
$$.from = $1; $$.from = $1;
$$.to = $3; $$.to = $3;
} }
| mem ',' con ',' imm | mem ',' con ',' imm3
{ {
$$.from = $1; $$.from = $1;
$$.from.scale = $3; $$.from.scale = $3;
...@@ -364,6 +364,14 @@ reg: ...@@ -364,6 +364,14 @@ reg:
$$.type = $1; $$.type = $1;
} }
imm3:
'$' con3
{
$$ = nullgen;
$$.type = D_CONST;
$$.offset = $2;
}
imm: imm:
'$' con '$' con
{ {
...@@ -548,6 +556,25 @@ con: ...@@ -548,6 +556,25 @@ con:
$$ = $2; $$ = $2;
} }
con3:
LCONST
| '-' LCONST
{
$$ = -$2;
}
| LCONST '-' LCONST '-' LCONST
{
$$ = ($1 & 0xffffffffLL) +
(($3 & 0xffffLL) << 32) +
(($5 & 0xffffLL) << 48);
}
| '-' LCONST '-' LCONST '-' LCONST
{
$$ = (-$2 & 0xffffffffLL) +
(($4 & 0xffffLL) << 32) +
(($6 & 0xffffLL) << 48);
}
expr: expr:
con con
| expr '+' expr | expr '+' expr
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#define NSNAME 8 #define NSNAME 8
#define NOPROF (1<<0) #define NOPROF (1<<0)
#define DUPOK (1<<1) #define DUPOK (1<<1)
#define NOSPLIT (1<<2)
#define SOFmark "\xa7\xf1\xd9\x2a\x82\xc8\xd8\xfe" #define SOFmark "\xa7\xf1\xd9\x2a\x82\xc8\xd8\xfe"
/* /*
......
...@@ -345,6 +345,9 @@ EXTERN int exports, nexports; ...@@ -345,6 +345,9 @@ EXTERN int exports, nexports;
EXTERN char* EXPTAB; EXTERN char* EXPTAB;
EXTERN Prog undefp; EXTERN Prog undefp;
EXTERN ulong stroffset; EXTERN ulong stroffset;
EXTERN vlong textstksiz;
EXTERN vlong textinarg;
EXTERN vlong textoutarg;
#define UP (&undefp) #define UP (&undefp)
...@@ -407,6 +410,7 @@ void objfile(char*); ...@@ -407,6 +410,7 @@ void objfile(char*);
int opsize(Prog*); int opsize(Prog*);
void patch(void); void patch(void);
Prog* prg(void); Prog* prg(void);
void parsetextconst(vlong);
void readundefs(char*, int); void readundefs(char*, int);
int relinv(int); int relinv(int);
long reuse(Prog*, Sym*); long reuse(Prog*, Sym*);
......
...@@ -56,10 +56,13 @@ Pconv(Fmt *fp) ...@@ -56,10 +56,13 @@ Pconv(Fmt *fp)
switch(p->as) { switch(p->as) {
case ATEXT: case ATEXT:
if(p->from.scale) { if(p->from.scale) {
sprint(str, "%-7s %-7A %D,%d,%D", sprint(str, "%-7s %-7A %D,%d,%lD",
str1, p->as, &p->from, p->from.scale, &p->to); str1, p->as, &p->from, p->from.scale, &p->to);
break; break;
} }
sprint(str, "%-7s %-7A %D,%lD",
str1, p->as, &p->from, &p->to);
break;
default: default:
sprint(str, "%-7s %-7A %D,%D", sprint(str, "%-7s %-7A %D,%D",
...@@ -95,6 +98,22 @@ Dconv(Fmt *fp) ...@@ -95,6 +98,22 @@ Dconv(Fmt *fp)
a = va_arg(fp->args, Adr*); a = va_arg(fp->args, Adr*);
i = a->type; i = a->type;
if(fp->flags & FmtLong) {
if(i != D_CONST) {
// ATEXT dst is not constant
sprint(str, "!!%D", a);
goto brk;
}
parsetextconst(a->offset);
if(textinarg == 0 && textoutarg == 0) {
sprint(str, "$%lld", textstksiz);
goto brk;
}
sprint(str, "$%lld-%lld-%lld", textstksiz, textinarg, textoutarg);
goto brk;
}
if(i >= D_INDIR) { if(i >= D_INDIR) {
if(a->offset) if(a->offset)
sprint(str, "%lld(%R)", a->offset, i-D_INDIR); sprint(str, "%lld(%R)", a->offset, i-D_INDIR);
...@@ -395,3 +414,26 @@ diag(char *fmt, ...) ...@@ -395,3 +414,26 @@ diag(char *fmt, ...)
errorexit(); errorexit();
} }
} }
void
parsetextconst(vlong arg)
{
textstksiz = arg & 0xffffffffLL;
if(textstksiz & 0x80000000LL)
textstksiz = -(-textstksiz & 0xffffffffLL);
// the following throws away one bit
// of precision, but maintains compat
textinarg = (arg >> 32) & 0xffffLL;
if(textinarg & 0x8000LL)
textinarg = -(-textinarg & 0xffffLL);
if(textinarg <= 0)
textinarg = 100;
textoutarg = (arg >> 48) & 0xffffLL;
if(textoutarg & 0x8000LL)
textoutarg = -(-textoutarg & 0xffffLL);
if(textoutarg <= 0)
textoutarg = 0;
}
...@@ -568,6 +568,23 @@ dostkoff(void) ...@@ -568,6 +568,23 @@ dostkoff(void)
Prog *p, *q; Prog *p, *q;
long autoffset, deltasp; long autoffset, deltasp;
int a, f, curframe, curbecome, maxbecome, pcsize; int a, f, curframe, curbecome, maxbecome, pcsize;
Prog *pmorestack;
Sym *symmorestack;
pmorestack = P;
symmorestack = lookup("_morestack", 0);
if(symmorestack->type == STEXT)
for(p = firstp; p != P; p = p->link) {
if(p->as == ATEXT) {
if(p->from.sym == symmorestack) {
pmorestack = p;
break;
}
}
}
if(pmorestack == P)
diag("_morestack not defined");
curframe = 0; curframe = 0;
curbecome = 0; curbecome = 0;
...@@ -643,15 +660,72 @@ dostkoff(void) ...@@ -643,15 +660,72 @@ dostkoff(void)
for(p = firstp; p != P; p = p->link) { for(p = firstp; p != P; p = p->link) {
if(p->as == ATEXT) { if(p->as == ATEXT) {
curtext = p; curtext = p;
autoffset = p->to.offset; parsetextconst(p->to.offset);
autoffset = textstksiz;
if(autoffset < 0) if(autoffset < 0)
autoffset = 0; autoffset = 0;
q = P;
if(pmorestack != P)
if(!(p->from.scale & NOSPLIT)) {
if(autoffset <= 50) {
// small stack
p = appendp(p);
p->as = ACMPQ;
p->from.type = D_SP;
p->to.type = D_INDIR+D_R15;
} else {
// large stack
p = appendp(p);
p->as = AMOVQ;
p->from.type = D_SP;
p->to.type = D_AX;
p = appendp(p);
p->as = ASUBQ;
p->from.type = D_CONST;
p->from.offset = autoffset-50;
p->to.type = D_AX;
p = appendp(p);
p->as = ACMPQ;
p->from.type = D_AX;
p->to.type = D_INDIR+D_R15;
}
// common
p = appendp(p);
p->as = AJHI;
p->to.type = D_BRANCH;
p->to.offset = 3;
q = p;
p = appendp(p);
p->as = AMOVQ;
p->from.type = D_CONST;
p->from.offset = curtext->to.offset;
p->to.type = D_AX;
p = appendp(p);
p->as = ACALL;
p->to.type = D_BRANCH;
p->pcond = pmorestack;
p->to.sym = symmorestack;
}
if(q != P)
q->pcond = p->link;
if(autoffset) { if(autoffset) {
p = appendp(p); p = appendp(p);
p->as = AADJSP; p->as = AADJSP;
p->from.type = D_CONST; p->from.type = D_CONST;
p->from.offset = autoffset; p->from.offset = autoffset;
if(q != P)
q->pcond = p;
} }
deltasp = autoffset; deltasp = autoffset;
} }
pcsize = p->mode/8; pcsize = p->mode/8;
......
...@@ -36,10 +36,10 @@ done: ...@@ -36,10 +36,10 @@ done:
POPQ AX POPQ AX
RET RET
TEXT FLUSH(SB),1,$-8 TEXT FLUSH(SB),7,$-8
RET RET
TEXT sys·exit(SB),1,$-8 TEXT sys·exit(SB),7,$-8
MOVL 8(SP), DI // arg 1 exit status MOVL 8(SP), DI // arg 1 exit status
MOVL $(0x2000000+1), AX MOVL $(0x2000000+1), AX
SYSCALL SYSCALL
......
...@@ -3,48 +3,59 @@ ...@@ -3,48 +3,59 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
TEXT _rt0_amd64_linux(SB),1,$-8 TEXT _rt0_amd64_linux(SB),7,$-8
PUSHQ $0
MOVQ SP, BP // copy arguments forward on an even stack
ANDQ $~15, SP
MOVQ 8(BP), DI // argc
LEAQ 16(BP), SI // argv MOVQ 0(SP), AX // argc
MOVL DI, DX LEAQ 8(SP), BX // argv
ADDL $1, DX ANDQ $~7, SP
SHLL $3, DX SUBQ $32, SP
ADDQ SI, DX MOVQ AX, 16(SP)
MOVQ DX, CX MOVQ BX, 24(SP)
CMPQ (CX), $0
JEQ done // allocate the per-user block
loop: LEAQ peruser<>(SB), R15 // dedicated u. register
ADDQ $8, CX MOVQ SP, AX
CMPQ (CX), $0 SUBQ $4096, AX
JNE loop MOVQ AX, 0(R15)
done:
ADDQ $8, CX
SUBQ $16, SP
MOVL DI, 0(SP)
MOVQ SI, 8(SP)
CALL args(SB)
ADDQ $16, SP
CALL check(SB) CALL check(SB)
// process the arguments
MOVL 16(SP), AX
MOVL AX, 0(SP)
MOVQ 24(SP), AX
MOVQ AX, 8(SP)
CALL args(SB)
CALL main·main(SB) CALL main·main(SB)
MOVQ $0, AX
MOVQ AX, 0(SP) // exit status
CALL sys·exit(SB) CALL sys·exit(SB)
CALL notok(SB) CALL notok(SB)
POPQ AX
ADDQ $32, SP
RET
TEXT _morestack(SB), 7, $0
MOVQ SP, AX
SUBQ $1024, AX
MOVQ AX, 0(R15)
RET RET
TEXT FLUSH(SB),1,$-8 TEXT FLUSH(SB),7,$-8
RET RET
TEXT sys·exit(SB),1,$-8 TEXT sys·exit(SB),1,$-8
MOVL 8(SP), DI MOVL 8(SP), DI
MOVL $60, AX MOVL $60, AX
SYSCALL SYSCALL
JCC 2(PC)
CALL notok(SB)
RET RET
TEXT sys·write(SB),1,$-8 TEXT sys·write(SB),1,$-8
...@@ -53,8 +64,6 @@ TEXT sys·write(SB),1,$-8 ...@@ -53,8 +64,6 @@ TEXT sys·write(SB),1,$-8
MOVL 24(SP), DX MOVL 24(SP), DX
MOVL $1, AX // syscall entry MOVL $1, AX // syscall entry
SYSCALL SYSCALL
JCC 2(PC)
CALL notok(SB)
RET RET
TEXT open(SB),1,$-8 TEXT open(SB),1,$-8
...@@ -93,8 +102,6 @@ TEXT sys·rt_sigaction(SB),1,$-8 ...@@ -93,8 +102,6 @@ TEXT sys·rt_sigaction(SB),1,$-8
MOVL CX, R10 MOVL CX, R10
MOVL $13, AX // syscall entry MOVL $13, AX // syscall entry
SYSCALL SYSCALL
JCC 2(PC)
CALL notok(SB)
RET RET
TEXT sigtramp(SB),1,$24 TEXT sigtramp(SB),1,$24
...@@ -151,3 +158,5 @@ TEXT sys·getcallerpc+0(SB),0,$0 ...@@ -151,3 +158,5 @@ TEXT sys·getcallerpc+0(SB),0,$0
MOVQ x+0(FP),AX MOVQ x+0(FP),AX
MOVQ -8(AX),AX MOVQ -8(AX),AX
RET RET
GLOBL peruser<>(SB),$64
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