summaryrefslogtreecommitdiff
path: root/src/cmd/6c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/6c')
-rw-r--r--src/cmd/6c/cgen.c14
-rw-r--r--src/cmd/6c/doc.go6
-rw-r--r--src/cmd/6c/gc.h3
-rw-r--r--src/cmd/6c/list.c55
-rw-r--r--src/cmd/6c/mul.c8
-rw-r--r--src/cmd/6c/peep.c40
-rw-r--r--src/cmd/6c/reg.c136
-rw-r--r--src/cmd/6c/sgen.c5
-rw-r--r--src/cmd/6c/swt.c47
-rw-r--r--src/cmd/6c/txt.c90
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)
{