diff options
author | Tianon Gravi <admwiggin@gmail.com> | 2015-01-15 11:54:00 -0700 |
---|---|---|
committer | Tianon Gravi <admwiggin@gmail.com> | 2015-01-15 11:54:00 -0700 |
commit | f154da9e12608589e8d5f0508f908a0c3e88a1bb (patch) | |
tree | f8255d51e10c6f1e0ed69702200b966c9556a431 /src/cmd/6c | |
parent | 8d8329ed5dfb9622c82a9fbec6fd99a580f9c9f6 (diff) | |
download | golang-upstream/1.4.tar.gz |
Imported Upstream version 1.4upstream/1.4
Diffstat (limited to 'src/cmd/6c')
-rw-r--r-- | src/cmd/6c/cgen.c | 36 | ||||
-rw-r--r-- | src/cmd/6c/gc.h | 5 | ||||
-rw-r--r-- | src/cmd/6c/reg.c | 14 | ||||
-rw-r--r-- | src/cmd/6c/sgen.c | 9 | ||||
-rw-r--r-- | src/cmd/6c/swt.c | 9 | ||||
-rw-r--r-- | src/cmd/6c/txt.c | 40 |
6 files changed, 73 insertions, 40 deletions
diff --git a/src/cmd/6c/cgen.c b/src/cmd/6c/cgen.c index bdef76ff0..68dd7bb5f 100644 --- a/src/cmd/6c/cgen.c +++ b/src/cmd/6c/cgen.c @@ -29,7 +29,7 @@ // THE SOFTWARE. #include "gc.h" -#include "../../pkg/runtime/funcdata.h" +#include "../../runtime/funcdata.h" /* ,x/^(print|prtree)\(/i/\/\/ */ int castup(Type*, Type*); @@ -51,7 +51,7 @@ cgen(Node *n, Node *nn) } if(n == Z || n->type == T) return; - if(typesu[n->type->etype]) { + if(typesu[n->type->etype] && (n->op != OFUNC || nn != Z)) { sugen(n, nn, n->type->width); return; } @@ -88,7 +88,7 @@ cgen(Node *n, Node *nn) if(cond(o) && typesu[l->type->etype]) break; - regret(&nod, r); + regret(&nod, r, 0, 0); cgen(r, &nod); regsalloc(&nod1, r); @@ -135,7 +135,7 @@ cgen(Node *n, Node *nn) if(!hardleft) { if(nn != Z || r->addable < INDEXED || hardconst(r)) { if(r->complex >= FNX && nn == Z) - regret(&nod, r); + regret(&nod, r, 0, 0); else regalloc(&nod, r, nn); cgen(r, &nod); @@ -929,7 +929,7 @@ cgen(Node *n, Node *nn) if(l->op != OIND) diag(n, "bad function call"); - regret(&nod, l->left); + regret(&nod, l->left, 0, 0); cgen(l->left, &nod); regsalloc(&nod1, l->left); gmove(&nod, &nod1); @@ -945,7 +945,6 @@ cgen(Node *n, Node *nn) return; } gargs(r, &nod, &nod1); - gpcdata(PCDATA_ArgSize, curarg); if(l->addable < INDEXED) { reglcgen(&nod, l, nn); nod.op = OREGISTER; @@ -953,14 +952,13 @@ cgen(Node *n, Node *nn) regfree(&nod); } else gopcode(OFUNC, n->type, Z, l); - gpcdata(PCDATA_ArgSize, -1); if(REGARG >= 0 && reg[REGARG]) reg[REGARG]--; - if(nn != Z) { - regret(&nod, n); + regret(&nod, n, l->type, 1); // update maxarg if nothing else + if(nn != Z) gmove(&nod, nn); + if(nod.op == OREGISTER) regfree(&nod); - } break; case OIND: @@ -1382,7 +1380,7 @@ boolgen(Node *n, int true, Node *nn) if(true) o = comrel[relindex(o)]; if(l->complex >= FNX && r->complex >= FNX) { - regret(&nod, r); + regret(&nod, r, 0, 0); cgen(r, &nod); regsalloc(&nod1, r); gmove(&nod, &nod1); @@ -1535,7 +1533,7 @@ sugen(Node *n, Node *nn, int32 w) if(nn != Z && side(nn)) { nod1 = *n; nod1.type = typ(TIND, n->type); - regret(&nod2, &nod1); + regret(&nod2, &nod1, 0, 0); lcgen(nn, &nod2); regsalloc(&nod0, &nod1); cgen(&nod2, &nod0); @@ -1617,6 +1615,20 @@ sugen(Node *n, Node *nn, int32 w) break; case OFUNC: + if(!hasdotdotdot(n->left->type)) { + cgen(n, Z); + if(nn != Z) { + curarg -= n->type->width; + regret(&nod1, n, n->left->type, 1); + if(nn->complex >= FNX) { + regsalloc(&nod2, n); + cgen(&nod1, &nod2); + nod1 = nod2; + } + cgen(&nod1, nn); + } + break; + } if(nn == Z) { sugen(n, nodrat, w); break; diff --git a/src/cmd/6c/gc.h b/src/cmd/6c/gc.h index a196e55a8..aa9d95d21 100644 --- a/src/cmd/6c/gc.h +++ b/src/cmd/6c/gc.h @@ -143,7 +143,6 @@ EXTERN int32 cursafe; EXTERN Prog* lastp; EXTERN int32 maxargsafe; EXTERN int mnstring; -EXTERN int retok; EXTERN Node* nodrat; EXTERN Node* nodret; EXTERN Node* nodsafe; @@ -211,7 +210,7 @@ void xcom(Node*); void indx(Node*); int bcomplex(Node*, Node*); Prog* gtext(Sym*, int32); -vlong argsize(void); +vlong argsize(int); /* * cgen.c @@ -240,7 +239,7 @@ Node* nodfconst(double); Node* nodgconst(vlong, Type*); int nodreg(Node*, Node*, int); int isreg(Node*, int); -void regret(Node*, Node*); +void regret(Node*, Node*, Type*, int); void regalloc(Node*, Node*, Node*); void regfree(Node*); void regialloc(Node*, Node*, Node*); diff --git a/src/cmd/6c/reg.c b/src/cmd/6c/reg.c index 348d747b7..6f8d3ce14 100644 --- a/src/cmd/6c/reg.c +++ b/src/cmd/6c/reg.c @@ -585,14 +585,11 @@ loop2: } rgp->cost = change; nregion++; - if(nregion >= NRGN) { - warn(Z, "too many regions"); - goto brk; - } + if(nregion >= NRGN) + fatal(Z, "too many regions"); rgp++; } } -brk: qsort(region, nregion, sizeof(region[0]), rcmp); /* @@ -808,11 +805,8 @@ mkvar(Reg *r, Addr *a) goto out; v++; } - if(nvar >= NVAR) { - if(debug['w'] > 1 && s) - warn(Z, "variable not optimized: %s", s->name); - goto none; - } + if(nvar >= NVAR) + fatal(Z, "variable not optimized: %s", s->name); i = nvar; nvar++; v = &var[i]; diff --git a/src/cmd/6c/sgen.c b/src/cmd/6c/sgen.c index ba1c1f652..fceb332b2 100644 --- a/src/cmd/6c/sgen.c +++ b/src/cmd/6c/sgen.c @@ -29,14 +29,14 @@ // THE SOFTWARE. #include "gc.h" -#include "../../pkg/runtime/funcdata.h" +#include "../../runtime/funcdata.h" Prog* gtext(Sym *s, int32 stkoff) { vlong v; - v = ((uvlong)argsize() << 32) | (stkoff & 0xffffffff); + v = ((uvlong)argsize(1) << 32) | (stkoff & 0xffffffff); if((textflag & NOSPLIT) && stkoff >= 128) yyerror("stack frame too large for NOSPLIT function"); @@ -124,10 +124,7 @@ xcom(Node *n) break; case ONAME: - if(flag_largemodel) - n->addable = 9; - else - n->addable = 10; + n->addable = 9; if(n->class == CPARAM || n->class == CAUTO) n->addable = 11; break; diff --git a/src/cmd/6c/swt.c b/src/cmd/6c/swt.c index d7713648d..6e918eb10 100644 --- a/src/cmd/6c/swt.c +++ b/src/cmd/6c/swt.c @@ -250,10 +250,11 @@ align(int32 i, Type *t, int op, int32 *maxalign) { int32 o; Type *v; - int w; + int w, packw; o = i; w = 1; + packw = 0; switch(op) { default: diag(Z, "unknown align opcode %d", op); @@ -264,7 +265,7 @@ align(int32 i, Type *t, int op, int32 *maxalign) if(w < 1) w = 1; if(packflg) - w = packflg; + packw = packflg; break; case Ael1: /* initial align of struct element */ @@ -277,7 +278,7 @@ align(int32 i, Type *t, int op, int32 *maxalign) if(w < 1 || w > SZ_VLONG) fatal(Z, "align"); if(packflg) - w = packflg; + packw = packflg; break; case Ael2: /* width of a struct element */ @@ -331,6 +332,8 @@ align(int32 i, Type *t, int op, int32 *maxalign) o = align(o, t, Ael2, nil); break; } + if(packw != 0 && xround(o, w) != xround(o, packw)) + diag(Z, "#pragma pack changes offset of %T", t); o = xround(o, w); if(maxalign && *maxalign < w) *maxalign = w; diff --git a/src/cmd/6c/txt.c b/src/cmd/6c/txt.c index 4d07436c3..3bdbf410e 100644 --- a/src/cmd/6c/txt.c +++ b/src/cmd/6c/txt.c @@ -351,15 +351,43 @@ nodreg(Node *n, Node *nn, int r) } void -regret(Node *n, Node *nn) +regret(Node *n, Node *nn, Type *t, int mode) { int r; + + if(mode == 0 || hasdotdotdot(t) || nn->type->width == 0) { + r = REGRET; + if(typefd[nn->type->etype]) + r = FREGRET; + nodreg(n, nn, r); + reg[r]++; + return; + } + + if(mode == 1) { + // fetch returned value after call. + // already called gargs, so curarg is set. + curarg = (curarg+7) & ~7; + regaalloc(n, nn); + return; + } - r = REGRET; - if(typefd[nn->type->etype]) - r = FREGRET; - nodreg(n, nn, r); - reg[r]++; + if(mode == 2) { + // store value to be returned. + // must compute arg offset. + if(t->etype != TFUNC) + fatal(Z, "bad regret func %T", t); + *n = *nn; + n->op = ONAME; + n->class = CPARAM; + n->sym = slookup(".ret"); + n->complex = nodret->complex; + n->addable = 20; + n->xoffset = argsize(0); + return; + } + + fatal(Z, "bad regret"); } void |