diff options
Diffstat (limited to 'src/cmd/6c')
-rw-r--r-- | src/cmd/6c/cgen.c | 14 | ||||
-rw-r--r-- | src/cmd/6c/doc.go | 6 | ||||
-rw-r--r-- | src/cmd/6c/gc.h | 3 | ||||
-rw-r--r-- | src/cmd/6c/list.c | 55 | ||||
-rw-r--r-- | src/cmd/6c/mul.c | 8 | ||||
-rw-r--r-- | src/cmd/6c/peep.c | 40 | ||||
-rw-r--r-- | src/cmd/6c/reg.c | 136 | ||||
-rw-r--r-- | src/cmd/6c/sgen.c | 5 | ||||
-rw-r--r-- | src/cmd/6c/swt.c | 47 | ||||
-rw-r--r-- | src/cmd/6c/txt.c | 90 |
10 files changed, 311 insertions, 93 deletions
diff --git a/src/cmd/6c/cgen.c b/src/cmd/6c/cgen.c index 71822586c..95400c445 100644 --- a/src/cmd/6c/cgen.c +++ b/src/cmd/6c/cgen.c @@ -265,6 +265,18 @@ cgen(Node *n, Node *nn) break; } } + if(n->op == OOR && l->op == OASHL && r->op == OLSHR + && l->right->op == OCONST && r->right->op == OCONST + && l->left->op == ONAME && r->left->op == ONAME + && l->left->sym == r->left->sym + && l->right->vconst + r->right->vconst == 8 * l->left->type->width) { + regalloc(&nod, l->left, nn); + cgen(l->left, &nod); + gopcode(OROTL, n->type, l->right, &nod); + gmove(&nod, nn); + regfree(&nod); + break; + } if(n->op == OADD && l->op == OASHL && l->right->op == OCONST && (r->op != OCONST || r->vconst < -128 || r->vconst > 127)) { c = l->right->vconst; @@ -1672,7 +1684,7 @@ copy: regsalloc(&nod2, nn); nn->type = t; - gins(AMOVL, &nod1, &nod2); + gins(AMOVQ, &nod1, &nod2); regfree(&nod1); nod2.type = typ(TIND, t); diff --git a/src/cmd/6c/doc.go b/src/cmd/6c/doc.go index 249a8ed80..e0a22e78b 100644 --- a/src/cmd/6c/doc.go +++ b/src/cmd/6c/doc.go @@ -2,13 +2,15 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build ignore + /* 6c is a version of the Plan 9 C compiler. The original is documented at - http://plan9.bell-labs.com/magic/man2html/1/2c + http://plan9.bell-labs.com/magic/man2html/1/8c Its target architecture is the x86-64, referred to by these tools as amd64. */ -package documentation +package main diff --git a/src/cmd/6c/gc.h b/src/cmd/6c/gc.h index b0081abb5..d1133ee21 100644 --- a/src/cmd/6c/gc.h +++ b/src/cmd/6c/gc.h @@ -292,6 +292,7 @@ void gbranch(int); void patch(Prog*, int32); int sconst(Node*); void gpseudo(int, Sym*, Node*); +void gprefetch(Node*); /* * swt.c @@ -366,8 +367,6 @@ int BtoF(int32); #define D_HI D_NONE #define D_LO D_NONE -#define isregtype(t) ((t)>= D_AX && (t)<=D_R15) - /* * bound */ diff --git a/src/cmd/6c/list.c b/src/cmd/6c/list.c index 4293203c0..b5a60ac9a 100644 --- a/src/cmd/6c/list.c +++ b/src/cmd/6c/list.c @@ -93,7 +93,7 @@ Pconv(Fmt *fp) break; default: - sprint(str, "(%L) %A %D,%lD", + sprint(str, "(%L) %A %D,%D", p->lineno, p->as, &p->from, &p->to); break; } @@ -120,13 +120,12 @@ Dconv(Fmt *fp) i = a->type; if(fp->flags & FmtLong) { - if(i != D_CONST) { + if(i == D_CONST) + sprint(str, "$%lld-%lld", a->offset&0xffffffffLL, a->offset>>32); + else { // ATEXT dst is not constant sprint(str, "!!%D", a); - goto brk; } - sprint(str, "$%lld-%lld", a->offset&0xffffffffLL, - (a->offset>>32)&0xffffffffLL); goto brk; } @@ -138,7 +137,6 @@ Dconv(Fmt *fp) goto brk; } switch(i) { - default: if(a->offset) sprint(str, "$%lld,%R", a->offset, i); @@ -151,7 +149,7 @@ Dconv(Fmt *fp) break; case D_BRANCH: - sprint(str, "%lld(PC)", a->offset-pc); + sprint(str, "%lld", a->offset); break; case D_EXTERN: @@ -159,24 +157,21 @@ Dconv(Fmt *fp) break; case D_STATIC: - sprint(str, "%s<>+%lld(SB)", a->sym->name, - a->offset); + sprint(str, "%s<>+%lld(SB)", a->sym->name, a->offset); break; case D_AUTO: - if(a->sym) { + if(a->sym) sprint(str, "%s+%lld(SP)", a->sym->name, a->offset); - break; - } - sprint(str, "%lld(SP)", a->offset); + else + sprint(str, "%lld(SP)", a->offset); break; case D_PARAM: - if(a->sym) { + if(a->sym) sprint(str, "%s+%lld(FP)", a->sym->name, a->offset); - break; - } - sprint(str, "%lld(FP)", a->offset); + else + sprint(str, "%lld(FP)", a->offset); break; case D_CONST: @@ -210,7 +205,7 @@ conv: char* regstr[] = { - "AL", /* [D_AL] */ + "AL", /* [D_AL] */ "CL", "DL", "BL", @@ -227,7 +222,7 @@ char* regstr[] = "R14B", "R15B", - "AX", /* [D_AX] */ + "AX", /* [D_AX] */ "CX", "DX", "BX", @@ -249,7 +244,7 @@ char* regstr[] = "DH", "BH", - "F0", /* [D_F0] */ + "F0", /* [D_F0] */ "F1", "F2", "F3", @@ -284,20 +279,20 @@ char* regstr[] = "X14", "X15", - "CS", /* [D_CS] */ + "CS", /* [D_CS] */ "SS", "DS", "ES", "FS", "GS", - "GDTR", /* [D_GDTR] */ - "IDTR", /* [D_IDTR] */ - "LDTR", /* [D_LDTR] */ - "MSW", /* [D_MSW] */ - "TASK", /* [D_TASK] */ + "GDTR", /* [D_GDTR] */ + "IDTR", /* [D_IDTR] */ + "LDTR", /* [D_LDTR] */ + "MSW", /* [D_MSW] */ + "TASK", /* [D_TASK] */ - "CR0", /* [D_CR] */ + "CR0", /* [D_CR] */ "CR1", "CR2", "CR3", @@ -314,7 +309,7 @@ char* regstr[] = "CR14", "CR15", - "DR0", /* [D_DR] */ + "DR0", /* [D_DR] */ "DR1", "DR2", "DR3", @@ -323,7 +318,7 @@ char* regstr[] = "DR6", "DR7", - "TR0", /* [D_TR] */ + "TR0", /* [D_TR] */ "TR1", "TR2", "TR3", @@ -332,7 +327,7 @@ char* regstr[] = "TR6", "TR7", - "NONE", /* [D_NONE] */ + "NONE", /* [D_NONE] */ }; int diff --git a/src/cmd/6c/mul.c b/src/cmd/6c/mul.c index ab6883e7a..510edc05c 100644 --- a/src/cmd/6c/mul.c +++ b/src/cmd/6c/mul.c @@ -35,17 +35,17 @@ typedef struct Mparam Mparam; struct Malg { - char vals[10]; + schar vals[10]; }; struct Mparam { uint32 value; - char alg; + schar alg; char neg; char shift; char arg; - char off; + schar off; }; static Mparam multab[32]; @@ -101,7 +101,7 @@ mulparam(uint32 m, Mparam *mp) { int c, i, j, n, o, q, s; int bc, bi, bn, bo, bq, bs, bt; - char *p; + schar *p; int32 u; uint32 t; diff --git a/src/cmd/6c/peep.c b/src/cmd/6c/peep.c index 8b82adbf5..c648d8c00 100644 --- a/src/cmd/6c/peep.c +++ b/src/cmd/6c/peep.c @@ -330,20 +330,7 @@ subprop(Reg *r0) case AIMULW: if(p->to.type != D_NONE) break; - - case ADIVB: - case ADIVL: - case ADIVQ: - case ADIVW: - case AIDIVB: - case AIDIVL: - case AIDIVQ: - case AIDIVW: - case AIMULB: - case AMULB: - case AMULL: - case AMULQ: - case AMULW: + goto giveup; case AROLB: case AROLL: @@ -369,6 +356,23 @@ subprop(Reg *r0) case ASHRL: case ASHRQ: case ASHRW: + if(p->from.type == D_CONST) + break; + goto giveup; + + case ADIVB: + case ADIVL: + case ADIVQ: + case ADIVW: + case AIDIVB: + case AIDIVL: + case AIDIVQ: + case AIDIVW: + case AIMULB: + case AMULB: + case AMULL: + case AMULQ: + case AMULW: case AREP: case AREPN: @@ -383,6 +387,8 @@ subprop(Reg *r0) case AMOVSB: case AMOVSL: case AMOVSQ: + case AMOVQL: + giveup: return 0; case AMOVL: @@ -581,6 +587,7 @@ copyu(Prog *p, Adr *v, Adr *s) case AMOVWLZX: case AMOVWQSX: case AMOVWQZX: + case AMOVQL: case AMOVSS: case AMOVSD: @@ -695,6 +702,11 @@ copyu(Prog *p, Adr *v, Adr *s) case ACMPB: case ACMPQ: + case APREFETCHT0: + case APREFETCHT1: + case APREFETCHT2: + case APREFETCHNTA: + case ACOMISD: case ACOMISS: case AUCOMISD: diff --git a/src/cmd/6c/reg.c b/src/cmd/6c/reg.c index 996128f75..e40e6c8f0 100644 --- a/src/cmd/6c/reg.c +++ b/src/cmd/6c/reg.c @@ -30,6 +30,8 @@ #include "gc.h" +static void fixjmp(Reg*); + Reg* rega(void) { @@ -185,6 +187,10 @@ regopt(Prog *p) case ACMPL: case ACMPQ: case ACMPW: + case APREFETCHT0: + case APREFETCHT1: + case APREFETCHT2: + case APREFETCHNTA: case ACOMISS: case ACOMISD: case AUCOMISS: @@ -211,6 +217,7 @@ regopt(Prog *p) case AMOVWLZX: case AMOVWQSX: case AMOVWQZX: + case AMOVQL: case AMOVSS: case AMOVSD: @@ -438,6 +445,12 @@ regopt(Prog *p) } /* + * pass 2.1 + * fix jumps + */ + fixjmp(firstr); + + /* * pass 2.5 * find looping structure */ @@ -1384,3 +1397,126 @@ BtoF(int32 b) return 0; return bitno(b) - 16 + FREGMIN; } + +/* what instruction does a JMP to p eventually land on? */ +static Reg* +chasejmp(Reg *r, int *jmploop) +{ + int n; + + n = 0; + for(; r; r=r->s2) { + if(r->prog->as != AJMP || r->prog->to.type != D_BRANCH) + break; + if(++n > 10) { + *jmploop = 1; + break; + } + } + return r; +} + +/* mark all code reachable from firstp as alive */ +static void +mark(Reg *firstr) +{ + Reg *r; + Prog *p; + + for(r=firstr; r; r=r->link) { + if(r->active) + break; + r->active = 1; + p = r->prog; + if(p->as != ACALL && p->to.type == D_BRANCH) + mark(r->s2); + if(p->as == AJMP || p->as == ARET || p->as == AUNDEF) + break; + } +} + +/* + * the code generator depends on being able to write out JMP + * instructions that it can jump to now but fill in later. + * the linker will resolve them nicely, but they make the code + * longer and more difficult to follow during debugging. + * remove them. + */ +static void +fixjmp(Reg *firstr) +{ + int jmploop; + Reg *r; + Prog *p; + + if(debug['R'] && debug['v']) + print("\nfixjmp\n"); + + // pass 1: resolve jump to AJMP, mark all code as dead. + jmploop = 0; + for(r=firstr; r; r=r->link) { + p = r->prog; + if(debug['R'] && debug['v']) + print("%04d %P\n", r->pc, p); + if(p->as != ACALL && p->to.type == D_BRANCH && r->s2 && r->s2->prog->as == AJMP) { + r->s2 = chasejmp(r->s2, &jmploop); + p->to.offset = r->s2->pc; + if(debug['R'] && debug['v']) + print("->%P\n", p); + } + r->active = 0; + } + if(debug['R'] && debug['v']) + print("\n"); + + // pass 2: mark all reachable code alive + mark(firstr); + + // pass 3: delete dead code (mostly JMPs). + for(r=firstr; r; r=r->link) { + if(!r->active) { + p = r->prog; + if(p->link == P && p->as == ARET && r->p1 && r->p1->prog->as != ARET) { + // This is the final ARET, and the code so far doesn't have one. + // Let it stay. + } else { + if(debug['R'] && debug['v']) + print("del %04d %P\n", r->pc, p); + p->as = ANOP; + } + } + } + + // pass 4: elide JMP to next instruction. + // only safe if there are no jumps to JMPs anymore. + if(!jmploop) { + for(r=firstr; r; r=r->link) { + p = r->prog; + if(p->as == AJMP && p->to.type == D_BRANCH && r->s2 == r->link) { + if(debug['R'] && debug['v']) + print("del %04d %P\n", r->pc, p); + p->as = ANOP; + } + } + } + + // fix back pointers. + for(r=firstr; r; r=r->link) { + r->p2 = R; + r->p2link = R; + } + for(r=firstr; r; r=r->link) { + if(r->s2) { + r->p2link = r->s2->p2; + r->s2->p2 = r; + } + } + + if(debug['R'] && debug['v']) { + print("\n"); + for(r=firstr; r; r=r->link) + print("%04d %P\n", r->pc, r->prog); + print("\n"); + } +} + diff --git a/src/cmd/6c/sgen.c b/src/cmd/6c/sgen.c index 42045f8fa..2402a020d 100644 --- a/src/cmd/6c/sgen.c +++ b/src/cmd/6c/sgen.c @@ -126,7 +126,10 @@ xcom(Node *n) break; case ONAME: - n->addable = 10; + if(flag_largemodel) + n->addable = 9; + else + n->addable = 10; 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 f16d0f78a..58d6d5129 100644 --- a/src/cmd/6c/swt.c +++ b/src/cmd/6c/swt.c @@ -247,18 +247,12 @@ outcode(void) Binit(&b, f, OWRITE); Bprint(&b, "go object %s %s %s\n", getgoos(), thestring, getgoversion()); - if(ndynimp > 0 || ndynexp > 0) { - int i; - + if(pragcgobuf.to > pragcgobuf.start) { Bprint(&b, "\n"); Bprint(&b, "$$ // exports\n\n"); Bprint(&b, "$$ // local types\n\n"); - Bprint(&b, "$$ // dynimport\n"); - for(i=0; i<ndynimp; i++) - Bprint(&b, "dynimport %s %s %s\n", dynimp[i].local, dynimp[i].remote, dynimp[i].path); - Bprint(&b, "\n$$ // dynexport\n"); - for(i=0; i<ndynexp; i++) - Bprint(&b, "dynexport %s %s\n", dynexp[i].local, dynexp[i].remote); + Bprint(&b, "$$ // cgo\n"); + Bprint(&b, "%s", fmtstrflush(&pragcgobuf)); Bprint(&b, "\n$$\n\n"); } Bprint(&b, "!\n"); @@ -339,12 +333,38 @@ outhist(Biobuf *b) char *p, *q, *op, c; Prog pg; int n; + char *tofree; + static int first = 1; + static char *goroot, *goroot_final; + + if(first) { + // Decide whether we need to rewrite paths from $GOROOT to $GOROOT_FINAL. + first = 0; + goroot = getenv("GOROOT"); + goroot_final = getenv("GOROOT_FINAL"); + if(goroot == nil) + goroot = ""; + if(goroot_final == nil) + goroot_final = goroot; + if(strcmp(goroot, goroot_final) == 0) { + goroot = nil; + goroot_final = nil; + } + } + tofree = nil; pg = zprog; pg.as = AHISTORY; c = pathchar(); for(h = hist; h != H; h = h->link) { p = h->name; + if(p != nil && goroot != nil) { + n = strlen(goroot); + if(strncmp(p, goroot, strlen(goroot)) == 0 && p[n] == '/') { + tofree = smprint("%s%s", goroot_final, p+n); + p = tofree; + } + } op = 0; if(systemtype(Windows) && p && p[1] == ':'){ c = p[2]; @@ -400,6 +420,11 @@ outhist(Biobuf *b) Bputc(b, pg.lineno>>24); zaddr(b, &pg.from, 0); zaddr(b, &pg.to, 0); + + if(tofree) { + free(tofree); + tofree = nil; + } } } @@ -591,8 +616,8 @@ align(int32 i, Type *t, int op, int32 *maxalign) int32 maxround(int32 max, int32 v) { - v += SZ_VLONG-1; + v = xround(v, SZ_VLONG); if(v > max) - max = xround(v, SZ_VLONG); + return v; return max; } diff --git a/src/cmd/6c/txt.c b/src/cmd/6c/txt.c index 2cb8c1585..364b189f2 100644 --- a/src/cmd/6c/txt.c +++ b/src/cmd/6c/txt.c @@ -809,7 +809,6 @@ gmove(Node *f, Node *t) case CASE( TUINT, TCHAR): case CASE( TLONG, TCHAR): case CASE( TULONG, TCHAR): - case CASE( TIND, TCHAR): case CASE( TCHAR, TUCHAR): case CASE( TUCHAR, TUCHAR): @@ -819,7 +818,6 @@ gmove(Node *f, Node *t) case CASE( TUINT, TUCHAR): case CASE( TLONG, TUCHAR): case CASE( TULONG, TUCHAR): - case CASE( TIND, TUCHAR): case CASE( TSHORT, TSHORT): case CASE( TUSHORT,TSHORT): @@ -827,7 +825,6 @@ gmove(Node *f, Node *t) case CASE( TUINT, TSHORT): case CASE( TLONG, TSHORT): case CASE( TULONG, TSHORT): - case CASE( TIND, TSHORT): case CASE( TSHORT, TUSHORT): case CASE( TUSHORT,TUSHORT): @@ -835,42 +832,26 @@ gmove(Node *f, Node *t) case CASE( TUINT, TUSHORT): case CASE( TLONG, TUSHORT): case CASE( TULONG, TUSHORT): - case CASE( TIND, TUSHORT): case CASE( TINT, TINT): case CASE( TUINT, TINT): case CASE( TLONG, TINT): case CASE( TULONG, TINT): - case CASE( TIND, TINT): case CASE( TINT, TUINT): case CASE( TUINT, TUINT): case CASE( TLONG, TUINT): case CASE( TULONG, TUINT): - case CASE( TIND, TUINT): - - case CASE( TUINT, TIND): - case CASE( TVLONG, TUINT): - case CASE( TVLONG, TULONG): - case CASE( TUVLONG, TUINT): - case CASE( TUVLONG, TULONG): *****/ a = AMOVL; break; - case CASE( TVLONG, TCHAR): - case CASE( TVLONG, TSHORT): - case CASE( TVLONG, TINT): - case CASE( TVLONG, TLONG): - case CASE( TUVLONG, TCHAR): - case CASE( TUVLONG, TSHORT): - case CASE( TUVLONG, TINT): - case CASE( TUVLONG, TLONG): + case CASE( TINT, TIND): case CASE( TINT, TVLONG): case CASE( TINT, TUVLONG): - case CASE( TLONG, TVLONG): - case CASE( TINT, TIND): case CASE( TLONG, TIND): + case CASE( TLONG, TVLONG): + case CASE( TLONG, TUVLONG): a = AMOVLQSX; if(f->op == OCONST) { f->vconst &= (uvlong)0xffffffffU; @@ -886,22 +867,53 @@ gmove(Node *f, Node *t) case CASE( TULONG, TVLONG): case CASE( TULONG, TUVLONG): case CASE( TULONG, TIND): - a = AMOVL; /* same effect as AMOVLQZX */ + a = AMOVLQZX; if(f->op == OCONST) { f->vconst &= (uvlong)0xffffffffU; a = AMOVQ; } break; + + case CASE( TIND, TCHAR): + case CASE( TIND, TUCHAR): + case CASE( TIND, TSHORT): + case CASE( TIND, TUSHORT): + case CASE( TIND, TINT): + case CASE( TIND, TUINT): + case CASE( TIND, TLONG): + case CASE( TIND, TULONG): + case CASE( TVLONG, TCHAR): + case CASE( TVLONG, TUCHAR): + case CASE( TVLONG, TSHORT): + case CASE( TVLONG, TUSHORT): + case CASE( TVLONG, TINT): + case CASE( TVLONG, TUINT): + case CASE( TVLONG, TLONG): + case CASE( TVLONG, TULONG): + case CASE( TUVLONG, TCHAR): + case CASE( TUVLONG, TUCHAR): + case CASE( TUVLONG, TSHORT): + case CASE( TUVLONG, TUSHORT): + case CASE( TUVLONG, TINT): + case CASE( TUVLONG, TUINT): + case CASE( TUVLONG, TLONG): + case CASE( TUVLONG, TULONG): + a = AMOVQL; + if(f->op == OCONST) { + f->vconst &= (int)0xffffffffU; + a = AMOVL; + } + break; + case CASE( TIND, TIND): case CASE( TIND, TVLONG): - case CASE( TVLONG, TVLONG): - case CASE( TUVLONG, TVLONG): - case CASE( TVLONG, TUVLONG): - case CASE( TUVLONG, TUVLONG): case CASE( TIND, TUVLONG): case CASE( TVLONG, TIND): + case CASE( TVLONG, TVLONG): + case CASE( TVLONG, TUVLONG): case CASE( TUVLONG, TIND): - case CASE( TIND, TIND): + case CASE( TUVLONG, TVLONG): + case CASE( TUVLONG, TUVLONG): a = AMOVQ; break; @@ -1348,6 +1360,16 @@ gopcode(int o, Type *ty, Node *f, Node *t) a = ASALQ; break; + case OROTL: + a = AROLL; + if(et == TCHAR || et == TUCHAR) + a = AROLB; + if(et == TSHORT || et == TUSHORT) + a = AROLW; + if(et == TVLONG || et == TUVLONG || et == TIND) + a = AROLQ; + break; + case OFUNC: a = ACALL; break; @@ -1490,6 +1512,18 @@ gpseudo(int a, Sym *s, Node *n) pc--; } +void +gprefetch(Node *n) +{ + Node n1; + + regalloc(&n1, n, Z); + gmove(n, &n1); + n1.op = OINDREG; + gins(APREFETCHNTA, &n1, Z); + regfree(&n1); +} + int sconst(Node *n) { |