summaryrefslogtreecommitdiff
path: root/src/cmd/8c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/8c')
-rw-r--r--src/cmd/8c/cgen.c35
-rw-r--r--src/cmd/8c/doc.go6
-rw-r--r--src/cmd/8c/gc.h1
-rw-r--r--src/cmd/8c/list.c64
-rw-r--r--src/cmd/8c/mul.c8
-rw-r--r--src/cmd/8c/peep.c6
-rw-r--r--src/cmd/8c/reg.c151
-rw-r--r--src/cmd/8c/swt.c47
-rw-r--r--src/cmd/8c/txt.c23
9 files changed, 302 insertions, 39 deletions
diff --git a/src/cmd/8c/cgen.c b/src/cmd/8c/cgen.c
index 869d31ace..78eb7eced 100644
--- a/src/cmd/8c/cgen.c
+++ b/src/cmd/8c/cgen.c
@@ -277,6 +277,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;
@@ -1703,6 +1715,7 @@ copy:
}
}
+ v = w == 8;
if(n->complex >= FNX && nn != nil && nn->complex >= FNX) {
t = nn->type;
nn->type = types[TLONG];
@@ -1728,8 +1741,28 @@ copy:
}
x = 0;
- v = w == 8;
if(v) {
+ if(nn != nil && nn->complex >= FNX) {
+ t = nn->type;
+ nn->type = types[TLONG];
+ regialloc(&nod2, nn, Z);
+ lcgen(nn, &nod2);
+ nn->type = t;
+
+ nod2.type = typ(TIND, t);
+
+ nod1 = nod2;
+ nod1.op = OIND;
+ nod1.left = &nod2;
+ nod1.right = Z;
+ nod1.complex = 1;
+ nod1.type = t;
+
+ sugen(n, &nod1, w);
+ regfree(&nod2);
+ return;
+ }
+
c = cursafe;
if(n->left != Z && n->left->complex >= FNX
&& n->right != Z && n->right->complex >= FNX) {
diff --git a/src/cmd/8c/doc.go b/src/cmd/8c/doc.go
index e3aae857f..0d07db14d 100644
--- a/src/cmd/8c/doc.go
+++ b/src/cmd/8c/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
+
/*
8c 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, referred to by these tools for historical reasons as 386.
*/
-package documentation
+package main
diff --git a/src/cmd/8c/gc.h b/src/cmd/8c/gc.h
index 4a57f5d3c..bdf981b4c 100644
--- a/src/cmd/8c/gc.h
+++ b/src/cmd/8c/gc.h
@@ -297,6 +297,7 @@ void gbranch(int);
void patch(Prog*, int32);
int sconst(Node*);
void gpseudo(int, Sym*, Node*);
+void gprefetch(Node*);
/*
* swt.c
diff --git a/src/cmd/8c/list.c b/src/cmd/8c/list.c
index c422905cd..8506e08ef 100644
--- a/src/cmd/8c/list.c
+++ b/src/cmd/8c/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;
}
@@ -118,6 +118,17 @@ Dconv(Fmt *fp)
a = va_arg(fp->args, Adr*);
i = a->type;
+
+ if(fp->flags & FmtLong) {
+ if(i == D_CONST2)
+ sprint(str, "$%d-%d", a->offset, a->offset2);
+ else {
+ // ATEXT dst is not constant
+ sprint(str, "!!%D", a);
+ }
+ goto brk;
+ }
+
if(i >= D_INDIR) {
if(a->offset)
sprint(str, "%d(%R)", a->offset, i-D_INDIR);
@@ -126,7 +137,6 @@ Dconv(Fmt *fp)
goto brk;
}
switch(i) {
-
default:
if(a->offset)
sprint(str, "$%d,%R", a->offset, i);
@@ -139,7 +149,7 @@ Dconv(Fmt *fp)
break;
case D_BRANCH:
- sprint(str, "%d(PC)", a->offset-pc);
+ sprint(str, "%d", a->offset);
break;
case D_EXTERN:
@@ -147,12 +157,14 @@ Dconv(Fmt *fp)
break;
case D_STATIC:
- sprint(str, "%s<>+%d(SB)", a->sym->name,
- a->offset);
+ sprint(str, "%s<>+%d(SB)", a->sym->name, a->offset);
break;
case D_AUTO:
- sprint(str, "%s+%d(SP)", a->sym->name, a->offset);
+ if(a->sym)
+ sprint(str, "%s+%d(SP)", a->sym->name, a->offset);
+ else
+ sprint(str, "%d(SP)", a->offset);
break;
case D_PARAM:
@@ -167,7 +179,10 @@ Dconv(Fmt *fp)
break;
case D_CONST2:
- sprint(str, "$%d-%d", a->offset, a->offset2);
+ if(!(fp->flags & FmtLong)) {
+ // D_CONST2 outside of ATEXT should not happen
+ sprint(str, "!!$%d-%d", a->offset, a->offset2);
+ }
break;
case D_FCONST:
@@ -197,7 +212,7 @@ conv:
char* regstr[] =
{
- "AL", /*[D_AL]*/
+ "AL", /* [D_AL] */
"CL",
"DL",
"BL",
@@ -206,7 +221,7 @@ char* regstr[] =
"DH",
"BH",
- "AX", /*[D_AX]*/
+ "AX", /* [D_AX] */
"CX",
"DX",
"BX",
@@ -215,7 +230,7 @@ char* regstr[] =
"SI",
"DI",
- "F0", /*[D_F0]*/
+ "F0", /* [D_F0] */
"F1",
"F2",
"F3",
@@ -224,20 +239,20 @@ char* regstr[] =
"F6",
"F7",
- "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",
@@ -246,7 +261,7 @@ char* regstr[] =
"CR6",
"CR7",
- "DR0", /*[D_DR]*/
+ "DR0", /* [D_DR] */
"DR1",
"DR2",
"DR3",
@@ -255,7 +270,7 @@ char* regstr[] =
"DR6",
"DR7",
- "TR0", /*[D_TR]*/
+ "TR0", /* [D_TR] */
"TR1",
"TR2",
"TR3",
@@ -264,7 +279,16 @@ char* regstr[] =
"TR6",
"TR7",
- "NONE", /*[D_NONE]*/
+ "X0", /* [D_X0] */
+ "X1",
+ "X2",
+ "X3",
+ "X4",
+ "X5",
+ "X6",
+ "X7",
+
+ "NONE", /* [D_NONE] */
};
int
diff --git a/src/cmd/8c/mul.c b/src/cmd/8c/mul.c
index a0742807e..9955e762f 100644
--- a/src/cmd/8c/mul.c
+++ b/src/cmd/8c/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/8c/peep.c b/src/cmd/8c/peep.c
index 9511a5579..9c3e9a5af 100644
--- a/src/cmd/8c/peep.c
+++ b/src/cmd/8c/peep.c
@@ -602,6 +602,12 @@ copyu(Prog *p, Adr *v, Adr *s)
case ACMPL: /* read only */
case ACMPW:
case ACMPB:
+
+ case APREFETCHT0:
+ case APREFETCHT1:
+ case APREFETCHT2:
+ case APREFETCHNTA:
+
case AFCOMB:
case AFCOMBP:
diff --git a/src/cmd/8c/reg.c b/src/cmd/8c/reg.c
index 6ba07bed2..6c87d70a5 100644
--- a/src/cmd/8c/reg.c
+++ b/src/cmd/8c/reg.c
@@ -30,6 +30,8 @@
#include "gc.h"
+static void fixjmp(Reg*);
+
Reg*
rega(void)
{
@@ -148,7 +150,6 @@ regopt(Prog *p)
r->p1 = R;
r1->s1 = R;
}
-
bit = mkvar(r, &p->from);
if(bany(&bit))
switch(p->as) {
@@ -182,6 +183,10 @@ regopt(Prog *p)
case ACMPB:
case ACMPL:
case ACMPW:
+ case APREFETCHT0:
+ case APREFETCHT1:
+ case APREFETCHT2:
+ case APREFETCHNTA:
for(z=0; z<BITS; z++)
r->use2.b[z] |= bit.b[z];
break;
@@ -372,6 +377,12 @@ regopt(Prog *p)
}
/*
+ * pass 2.1
+ * fix jumps
+ */
+ fixjmp(firstr);
+
+ /*
* pass 2.5
* find looping structure
*/
@@ -543,6 +554,13 @@ brk:
if(!debug['R'] || debug['P'])
peep();
+ if(debug['R'] && debug['v']) {
+ print("after pass 7 (peep)\n");
+ for(r=firstr; r; r=r->link)
+ print("%04d %P\n", r->pc, r->prog);
+ print("\n");
+ }
+
/*
* pass 8
* recalculate pc
@@ -596,6 +614,14 @@ brk:
while(p->link && p->link->as == ANOP)
p->link = p->link->link;
}
+
+ if(debug['R'] && debug['v']) {
+ print("after pass 8 (fixup pc)\n");
+ for(p1=firstr->prog; p1!=P; p1=p1->link)
+ print("%P\n", p1);
+ print("\n");
+ }
+
if(r1 != R) {
r1->link = freer;
freer = firstr;
@@ -1285,3 +1311,126 @@ BtoR(int32 b)
return 0;
return bitno(b) + D_AX;
}
+
+/* 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/8c/swt.c b/src/cmd/8c/swt.c
index f1ca4c25f..d331eee1a 100644
--- a/src/cmd/8c/swt.c
+++ b/src/cmd/8c/swt.c
@@ -251,18 +251,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");
@@ -343,12 +337,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];
@@ -404,6 +424,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;
+ }
}
}
@@ -597,8 +622,8 @@ align(int32 i, Type *t, int op, int32 *maxalign)
int32
maxround(int32 max, int32 v)
{
- v += SZ_LONG-1;
+ v = xround(v, SZ_LONG);
if(v > max)
- max = xround(v, SZ_LONG);
+ return v;
return max;
}
diff --git a/src/cmd/8c/txt.c b/src/cmd/8c/txt.c
index 3a08da7cd..1b7617bc5 100644
--- a/src/cmd/8c/txt.c
+++ b/src/cmd/8c/txt.c
@@ -1253,6 +1253,14 @@ gopcode(int o, Type *ty, Node *f, Node *t)
a = ASALW;
break;
+ case OROTL:
+ a = AROLL;
+ if(et == TCHAR || et == TUCHAR)
+ a = AROLB;
+ if(et == TSHORT || et == TUSHORT)
+ a = AROLW;
+ break;
+
case OFUNC:
a = ACALL;
break;
@@ -1383,6 +1391,21 @@ gpseudo(int a, Sym *s, Node *n)
pc--;
}
+void
+gprefetch(Node *n)
+{
+ Node n1;
+
+ if(strcmp(getgo386(), "sse2") != 0) // assume no prefetch on old machines
+ return;
+
+ regalloc(&n1, n, Z);
+ gmove(n, &n1);
+ n1.op = OINDREG;
+ gins(APREFETCHNTA, &n1, Z);
+ regfree(&n1);
+}
+
int
sconst(Node *n)
{