Commit 4e141145 authored by Russ Cox's avatar Russ Cox

cmd/5c, cmd/6c, cmd/8c: record arg size for every call

R=ken2
CC=golang-dev
https://golang.org/cl/11364043
parent 9ddfb643
...@@ -28,8 +28,8 @@ ...@@ -28,8 +28,8 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#include "gc.h" #include "gc.h"
#include "../../pkg/runtime/funcdata.h"
void void
_cgen(Node *n, Node *nn, int inrel) _cgen(Node *n, Node *nn, int inrel)
...@@ -366,12 +366,14 @@ _cgen(Node *n, Node *nn, int inrel) ...@@ -366,12 +366,14 @@ _cgen(Node *n, Node *nn, int inrel)
if(REGARG >= 0) if(REGARG >= 0)
o = reg[REGARG]; o = reg[REGARG];
gargs(r, &nod, &nod1); gargs(r, &nod, &nod1);
gpcdata(PCDATA_ArgSize, curarg);
if(l->addable < INDEXED) { if(l->addable < INDEXED) {
reglcgen(&nod, l, Z); reglcgen(&nod, l, Z);
gopcode(OFUNC, Z, Z, &nod); gopcode(OFUNC, Z, Z, &nod);
regfree(&nod); regfree(&nod);
} else } else
gopcode(OFUNC, Z, Z, l); gopcode(OFUNC, Z, Z, l);
gpcdata(PCDATA_ArgSize, -1);
if(REGARG >= 0) if(REGARG >= 0)
if(o != reg[REGARG]) if(o != reg[REGARG])
reg[REGARG]--; reg[REGARG]--;
......
...@@ -298,6 +298,7 @@ int sconst(Node*); ...@@ -298,6 +298,7 @@ int sconst(Node*);
int sval(int32); int sval(int32);
void gpseudo(int, Sym*, Node*); void gpseudo(int, Sym*, Node*);
void gprefetch(Node*); void gprefetch(Node*);
void gpcdata(int, int);
/* /*
* swt.c * swt.c
......
...@@ -37,8 +37,13 @@ gtext(Sym *s, int32 stkoff) ...@@ -37,8 +37,13 @@ gtext(Sym *s, int32 stkoff)
int32 a; int32 a;
a = 0; a = 0;
if(!(textflag & NOSPLIT)) if(!(textflag & NOSPLIT) || !hasdotdotdot()) {
a = argsize(); a = argsize();
// Change argsize 0 to 1 to be mark that
// the argument size is present.
if(a == 0)
a = 1;
}
else if(stkoff >= 128) else if(stkoff >= 128)
yyerror("stack frame too large for NOSPLIT function"); yyerror("stack frame too large for NOSPLIT function");
......
...@@ -1197,6 +1197,15 @@ gpseudo(int a, Sym *s, Node *n) ...@@ -1197,6 +1197,15 @@ gpseudo(int a, Sym *s, Node *n)
pc--; pc--;
} }
void
gpcdata(int index, int value)
{
Node n1;
n1 = *nodconst(index);
gins(APCDATA, &n1, nodconst(value));
}
void void
gprefetch(Node *n) gprefetch(Node *n)
{ {
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#include "gc.h" #include "gc.h"
#include "../../pkg/runtime/funcdata.h"
/* ,x/^(print|prtree)\(/i/\/\/ */ /* ,x/^(print|prtree)\(/i/\/\/ */
int castup(Type*, Type*); int castup(Type*, Type*);
...@@ -944,6 +945,7 @@ cgen(Node *n, Node *nn) ...@@ -944,6 +945,7 @@ cgen(Node *n, Node *nn)
return; return;
} }
gargs(r, &nod, &nod1); gargs(r, &nod, &nod1);
gpcdata(PCDATA_ArgSize, curarg);
if(l->addable < INDEXED) { if(l->addable < INDEXED) {
reglcgen(&nod, l, nn); reglcgen(&nod, l, nn);
nod.op = OREGISTER; nod.op = OREGISTER;
...@@ -951,6 +953,7 @@ cgen(Node *n, Node *nn) ...@@ -951,6 +953,7 @@ cgen(Node *n, Node *nn)
regfree(&nod); regfree(&nod);
} else } else
gopcode(OFUNC, n->type, Z, l); gopcode(OFUNC, n->type, Z, l);
gpcdata(PCDATA_ArgSize, -1);
if(REGARG >= 0 && reg[REGARG]) if(REGARG >= 0 && reg[REGARG])
reg[REGARG]--; reg[REGARG]--;
if(nn != Z) { if(nn != Z) {
......
...@@ -293,6 +293,7 @@ void patch(Prog*, int32); ...@@ -293,6 +293,7 @@ void patch(Prog*, int32);
int sconst(Node*); int sconst(Node*);
void gpseudo(int, Sym*, Node*); void gpseudo(int, Sym*, Node*);
void gprefetch(Node*); void gprefetch(Node*);
void gpcdata(int, int);
/* /*
* swt.c * swt.c
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#include "gc.h" #include "gc.h"
#include "../../pkg/runtime/funcdata.h"
Prog* Prog*
gtext(Sym *s, int32 stkoff) gtext(Sym *s, int32 stkoff)
...@@ -36,8 +37,14 @@ gtext(Sym *s, int32 stkoff) ...@@ -36,8 +37,14 @@ gtext(Sym *s, int32 stkoff)
vlong v; vlong v;
v = 0; v = 0;
if(!(textflag & NOSPLIT)) if(!(textflag & NOSPLIT) || !hasdotdotdot()) {
v |= argsize() << 32; v = argsize();
// Change argsize 0 to 1 to be mark that
// the argument size is present.
if(v == 0)
v = 1;
v <<= 32;
}
v |= stkoff & 0xffffffff; v |= stkoff & 0xffffffff;
if((textflag & NOSPLIT) && stkoff >= 128) if((textflag & NOSPLIT) && stkoff >= 128)
yyerror("stack frame too large for NOSPLIT function"); yyerror("stack frame too large for NOSPLIT function");
......
...@@ -1518,6 +1518,15 @@ gpseudo(int a, Sym *s, Node *n) ...@@ -1518,6 +1518,15 @@ gpseudo(int a, Sym *s, Node *n)
pc--; pc--;
} }
void
gpcdata(int index, int value)
{
Node n1;
n1 = *nodconst(index);
gins(APCDATA, &n1, nodconst(value));
}
void void
gprefetch(Node *n) gprefetch(Node *n)
{ {
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#include "gc.h" #include "gc.h"
#include "../../pkg/runtime/funcdata.h"
/* ,x/^(print|prtree)\(/i/\/\/ */ /* ,x/^(print|prtree)\(/i/\/\/ */
...@@ -937,6 +938,7 @@ cgen(Node *n, Node *nn) ...@@ -937,6 +938,7 @@ cgen(Node *n, Node *nn)
return; return;
} }
gargs(r, &nod, &nod1); gargs(r, &nod, &nod1);
gpcdata(PCDATA_ArgSize, curarg);
if(l->addable < INDEXED) { if(l->addable < INDEXED) {
reglcgen(&nod, l, nn); reglcgen(&nod, l, nn);
nod.op = OREGISTER; nod.op = OREGISTER;
...@@ -944,6 +946,7 @@ cgen(Node *n, Node *nn) ...@@ -944,6 +946,7 @@ cgen(Node *n, Node *nn)
regfree(&nod); regfree(&nod);
} else } else
gopcode(OFUNC, n->type, Z, l); gopcode(OFUNC, n->type, Z, l);
gpcdata(PCDATA_ArgSize, -1);
if(REGARG >= 0 && reg[REGARG]) if(REGARG >= 0 && reg[REGARG])
reg[REGARG]--; reg[REGARG]--;
if(nn != Z) { if(nn != Z) {
......
...@@ -298,6 +298,7 @@ void patch(Prog*, int32); ...@@ -298,6 +298,7 @@ void patch(Prog*, int32);
int sconst(Node*); int sconst(Node*);
void gpseudo(int, Sym*, Node*); void gpseudo(int, Sym*, Node*);
void gprefetch(Node*); void gprefetch(Node*);
void gpcdata(int, int);
/* /*
* swt.c * swt.c
......
...@@ -36,8 +36,13 @@ gtext(Sym *s, int32 stkoff) ...@@ -36,8 +36,13 @@ gtext(Sym *s, int32 stkoff)
int32 a; int32 a;
a = 0; a = 0;
if(!(textflag & NOSPLIT)) if(!(textflag & NOSPLIT) || !hasdotdotdot()) {
a = argsize(); a = argsize();
// Change argsize 0 to 1 to be mark that
// the argument size is present.
if(a == 0)
a = 1;
}
else if(stkoff >= 128) else if(stkoff >= 128)
yyerror("stack frame too large for NOSPLIT function"); yyerror("stack frame too large for NOSPLIT function");
......
...@@ -1397,6 +1397,15 @@ gpseudo(int a, Sym *s, Node *n) ...@@ -1397,6 +1397,15 @@ gpseudo(int a, Sym *s, Node *n)
pc--; pc--;
} }
void
gpcdata(int index, int value)
{
Node n1;
n1 = *nodconst(index);
gins(APCDATA, &n1, nodconst(value));
}
void void
gprefetch(Node *n) gprefetch(Node *n)
{ {
......
...@@ -777,6 +777,7 @@ void xcom(Node*); ...@@ -777,6 +777,7 @@ void xcom(Node*);
int32 exreg(Type*); int32 exreg(Type*);
int32 align(int32, Type*, int, int32*); int32 align(int32, Type*, int, int32*);
int32 maxround(int32, int32); int32 maxround(int32, int32);
int hasdotdotdot(void);
extern schar ewidth[]; extern schar ewidth[];
......
...@@ -30,6 +30,17 @@ ...@@ -30,6 +30,17 @@
#include "gc.h" #include "gc.h"
int
hasdotdotdot(void)
{
Type *t;
for(t=thisfn->down; t!=T; t=t->down)
if(t->etype == TDOT)
return 1;
return 0;
}
vlong vlong
argsize(void) argsize(void)
{ {
......
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