1
0
mirror of https://github.com/golang/go synced 2024-11-12 07:00:21 -07:00

cmd/5a, cmd/5c, cmd/6a, cmd/6c, cmd/8a, cmd/8c, cmd/cc: support for Native Client

From the original description in CL 15770043

The main change here is to consult $GOARCH.

In 6c, when GOOS=nacl, some of the more complex addressing modes must be disabled, and the BP and R15 registers must not be used.

See golang.org/s/go13nacl for design overview.

LGTM=rsc
R=golang-codereviews, gobot, rsc
CC=golang-codereviews
https://golang.org/cl/69020044
This commit is contained in:
Dave Cheney 2014-02-27 06:57:06 +11:00
parent 77ac8ecbeb
commit 7954b2b90b
13 changed files with 96 additions and 19 deletions

View File

@ -73,6 +73,12 @@ main(int argc, char *argv[])
listinit5(); listinit5();
fmtinstall('L', Lconv); fmtinstall('L', Lconv);
// Allow GOARCH=thestring or GOARCH=thestringsuffix,
// but not other values.
p = getgoarch();
if(strncmp(p, thestring, strlen(thestring)) != 0)
sysfatal("cannot use %cc with GOARCH=%s", thechar, p);
ensuresymb(NSYMB); ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug)); memset(debug, 0, sizeof(debug));
cinit(); cinit();
@ -162,7 +168,7 @@ assemble(char *file)
errorexit(); errorexit();
} }
Binit(&obuf, of, OWRITE); Binit(&obuf, of, OWRITE);
Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion()); Bprint(&obuf, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
Bprint(&obuf, "!\n"); Bprint(&obuf, "!\n");
for(pass = 1; pass <= 2; pass++) { for(pass = 1; pass <= 2; pass++) {

View File

@ -354,7 +354,7 @@ gextern(Sym *s, Node *a, int32 o, int32 w)
void void
outcode(void) outcode(void)
{ {
Bprint(&outbuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion()); Bprint(&outbuf, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
if(pragcgobuf.to > pragcgobuf.start) { if(pragcgobuf.to > pragcgobuf.start) {
Bprint(&outbuf, "\n"); Bprint(&outbuf, "\n");
Bprint(&outbuf, "$$ // exports\n\n"); Bprint(&outbuf, "$$ // exports\n\n");

View File

@ -33,13 +33,14 @@
LinkArch *thelinkarch = &linkarm; LinkArch *thelinkarch = &linkarm;
int thechar = '5';
char *thestring = "arm";
void void
ginit(void) ginit(void)
{ {
Type *t; Type *t;
thechar = '5';
thestring = "arm";
exregoffset = REGEXT; exregoffset = REGEXT;
exfregoffset = FREGEXT; exfregoffset = FREGEXT;
listinit(); listinit();

View File

@ -79,6 +79,12 @@ main(int argc, char *argv[])
listinit6(); listinit6();
fmtinstall('L', Lconv); fmtinstall('L', Lconv);
// Allow GOARCH=thestring or GOARCH=thestringsuffix,
// but not other values.
p = getgoarch();
if(strncmp(p, thestring, strlen(thestring)) != 0)
sysfatal("cannot use %cc with GOARCH=%s", thechar, p);
ensuresymb(NSYMB); ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug)); memset(debug, 0, sizeof(debug));
cinit(); cinit();
@ -164,7 +170,7 @@ assemble(char *file)
errorexit(); errorexit();
} }
Binit(&obuf, of, OWRITE); Binit(&obuf, of, OWRITE);
Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion()); Bprint(&obuf, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
Bprint(&obuf, "!\n"); Bprint(&obuf, "!\n");
for(pass = 1; pass <= 2; pass++) { for(pass = 1; pass <= 2; pass++) {

View File

@ -717,7 +717,7 @@ addmove(Reg *r, int bn, int rn, int f)
p1->as = AMOVB; p1->as = AMOVB;
if(v->etype == TSHORT || v->etype == TUSHORT) if(v->etype == TSHORT || v->etype == TUSHORT)
p1->as = AMOVW; p1->as = AMOVW;
if(v->etype == TVLONG || v->etype == TUVLONG || v->etype == TIND) if(v->etype == TVLONG || v->etype == TUVLONG || (v->etype == TIND && ewidth[TIND] == 8))
p1->as = AMOVQ; p1->as = AMOVQ;
if(v->etype == TFLOAT) if(v->etype == TFLOAT)
p1->as = AMOVSS; p1->as = AMOVSS;
@ -1373,6 +1373,8 @@ BtoR(int32 b)
{ {
b &= 0xffffL; b &= 0xffffL;
if(nacl)
b &= ~((1<<(D_BP-D_AX)) | (1<<(D_R15-D_AX)));
if(b == 0) if(b == 0)
return 0; return 0;
return bitno(b) + D_AX; return bitno(b) + D_AX;

View File

@ -207,7 +207,7 @@ xcom(Node *n)
n->addable = 8; n->addable = 8;
break; break;
} }
if(n->addable == 8 && !side(n)) { if(n->addable == 8 && !side(n) && !nacl) {
indx(n); indx(n);
l = new1(OINDEX, idx.basetree, idx.regtree); l = new1(OINDEX, idx.basetree, idx.regtree);
l->scale = idx.scale; l->scale = idx.scale;

View File

@ -228,7 +228,7 @@ outcode(void)
} }
Binit(&b, f, OWRITE); Binit(&b, f, OWRITE);
Bprint(&b, "go object %s %s %s\n", getgoos(), thestring, getgoversion()); Bprint(&b, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
if(pragcgobuf.to > pragcgobuf.start) { if(pragcgobuf.to > pragcgobuf.start) {
Bprint(&b, "\n"); Bprint(&b, "\n");
Bprint(&b, "$$ // exports\n\n"); Bprint(&b, "$$ // exports\n\n");
@ -292,6 +292,21 @@ align(int32 i, Type *t, int op, int32 *maxalign)
break; break;
case Aarg1: /* initial align of parameter */ case Aarg1: /* initial align of parameter */
if(ewidth[TIND] == 4) {
if(typesu[t->etype]) {
for(v = t->link; v != T; v = v->down)
o = align(o, v, Aarg1, maxalign);
goto out;
}
w = ewidth[t->etype];
if(typev[t->etype] || t->etype == TDOUBLE)
w = 8;
else if(w <= 0 || w >= 4)
w = 4;
else
w = 1;
break;
}
w = ewidth[t->etype]; w = ewidth[t->etype];
if(w <= 0 || w >= SZ_VLONG) { if(w <= 0 || w >= SZ_VLONG) {
w = SZ_VLONG; w = SZ_VLONG;
@ -302,6 +317,10 @@ align(int32 i, Type *t, int op, int32 *maxalign)
case Aarg2: /* width of a parameter */ case Aarg2: /* width of a parameter */
o += t->width; o += t->width;
if(ewidth[TIND] == 4) {
o = align(o, t, Aarg1, maxalign);
goto out;
}
w = t->width; w = t->width;
if(w > SZ_VLONG) if(w > SZ_VLONG)
w = SZ_VLONG; w = SZ_VLONG;
@ -315,6 +334,7 @@ align(int32 i, Type *t, int op, int32 *maxalign)
o = xround(o, w); o = xround(o, w);
if(maxalign && *maxalign < w) if(maxalign && *maxalign < w)
*maxalign = w; *maxalign = w;
out:
if(debug['A']) if(debug['A'])
print("align %s %d %T = %d\n", bnames[op], i, t, o); print("align %s %d %T = %d\n", bnames[op], i, t, o);
return o; return o;

View File

@ -32,15 +32,18 @@
LinkArch *thelinkarch = &linkamd64; LinkArch *thelinkarch = &linkamd64;
int thechar = '6';
char *thestring = "amd64";
void void
ginit(void) ginit(void)
{ {
int i; int i;
Type *t; Type *t;
thechar = '6'; dodefine("_64BITREG");
thestring = "amd64"; if(ewidth[TIND] == 8)
dodefine("_64BIT"); dodefine("_64BIT");
listinit(); listinit();
nstring = 0; nstring = 0;
mnstring = 0; mnstring = 0;
@ -130,6 +133,10 @@ ginit(void)
if(i >= D_X0 && i <= D_X7) if(i >= D_X0 && i <= D_X7)
reg[i] = 0; reg[i] = 0;
} }
if(nacl) {
reg[D_BP] = 1;
reg[D_R15] = 1;
}
} }
void void
@ -139,6 +146,10 @@ gclean(void)
Sym *s; Sym *s;
reg[D_SP]--; reg[D_SP]--;
if(nacl) {
reg[D_BP]--;
reg[D_R15]--;
}
for(i=D_AX; i<=D_R15; i++) for(i=D_AX; i<=D_R15; i++)
if(reg[i]) if(reg[i])
diag(Z, "reg %R left allocated", i); diag(Z, "reg %R left allocated", i);
@ -569,7 +580,7 @@ naddr(Node *n, Addr *a)
} }
a->sym = nil; a->sym = nil;
a->type = D_CONST; a->type = D_CONST;
if(typev[n->type->etype] || n->type->etype == TIND) if(typev[n->type->etype] || (n->type->etype == TIND && ewidth[TIND] == 8))
a->offset = n->vconst; a->offset = n->vconst;
else else
a->offset = convvtox(n->vconst, typeu[n->type->etype]? TULONG: TLONG); a->offset = convvtox(n->vconst, typeu[n->type->etype]? TULONG: TLONG);
@ -632,6 +643,12 @@ gmove(Node *f, Node *t)
ft = f->type->etype; ft = f->type->etype;
tt = t->type->etype; tt = t->type->etype;
if(ewidth[TIND] == 4) {
if(ft == TIND)
ft = TUINT;
if(tt == TIND)
tt = TUINT;
}
t64 = tt == TVLONG || tt == TUVLONG || tt == TIND; t64 = tt == TVLONG || tt == TUVLONG || tt == TIND;
if(debug['M']) if(debug['M'])
print("gop: %O %O[%s],%O[%s]\n", OAS, print("gop: %O %O[%s],%O[%s]\n", OAS,
@ -723,6 +740,8 @@ gmove(Node *f, Node *t)
goto ld; goto ld;
case TIND: case TIND:
a = AMOVQ; a = AMOVQ;
if(ewidth[TIND] == 4)
a = AMOVL;
ld: ld:
regalloc(&nod, f, t); regalloc(&nod, f, t);
@ -1228,6 +1247,8 @@ gopcode(int o, Type *ty, Node *f, Node *t)
et = TLONG; et = TLONG;
if(ty != T) if(ty != T)
et = ty->etype; et = ty->etype;
if(et == TIND && ewidth[TIND] == 4)
et = TUINT;
if(debug['M']) { if(debug['M']) {
if(f != Z && f->type != T) if(f != Z && f->type != T)
print("gop: %O %O[%s],", o, f->op, tnames[et]); print("gop: %O %O[%s],", o, f->op, tnames[et]);
@ -1564,7 +1585,7 @@ exreg(Type *t)
if(exregoffset >= 64) if(exregoffset >= 64)
return 0; return 0;
o = exregoffset; o = exregoffset;
exregoffset += 8; exregoffset += ewidth[TIND];
return o+1; // +1 to avoid 0 == failure; naddr's case OEXREG will subtract 1. return o+1; // +1 to avoid 0 == failure; naddr's case OEXREG will subtract 1.
} }
return 0; return 0;

View File

@ -79,6 +79,12 @@ main(int argc, char *argv[])
listinit8(); listinit8();
fmtinstall('L', Lconv); fmtinstall('L', Lconv);
// Allow GOARCH=thestring or GOARCH=thestringsuffix,
// but not other values.
p = getgoarch();
if(strncmp(p, thestring, strlen(thestring)) != 0)
sysfatal("cannot use %cc with GOARCH=%s", thechar, p);
ensuresymb(NSYMB); ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug)); memset(debug, 0, sizeof(debug));
cinit(); cinit();
@ -163,7 +169,7 @@ assemble(char *file)
errorexit(); errorexit();
} }
Binit(&obuf, of, OWRITE); Binit(&obuf, of, OWRITE);
Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion()); Bprint(&obuf, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
Bprint(&obuf, "!\n"); Bprint(&obuf, "!\n");
for(pass = 1; pass <= 2; pass++) { for(pass = 1; pass <= 2; pass++) {

View File

@ -233,7 +233,7 @@ outcode(void)
} }
Binit(&b, f, OWRITE); Binit(&b, f, OWRITE);
Bprint(&b, "go object %s %s %s\n", getgoos(), thestring, getgoversion()); Bprint(&b, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
if(pragcgobuf.to > pragcgobuf.start) { if(pragcgobuf.to > pragcgobuf.start) {
Bprint(&b, "\n"); Bprint(&b, "\n");
Bprint(&b, "$$ // exports\n\n"); Bprint(&b, "$$ // exports\n\n");

View File

@ -32,14 +32,15 @@
LinkArch *thelinkarch = &link386; LinkArch *thelinkarch = &link386;
int thechar = '8';
char *thestring = "386";
void void
ginit(void) ginit(void)
{ {
int i; int i;
Type *t; Type *t;
thechar = '8';
thestring = "386";
exregoffset = 0; exregoffset = 0;
exfregoffset = 0; exfregoffset = 0;
listinit(); listinit();

View File

@ -506,8 +506,8 @@ EXTERN Sym* symstring;
EXTERN int taggen; EXTERN int taggen;
EXTERN Type* tfield; EXTERN Type* tfield;
EXTERN Type* tufield; EXTERN Type* tufield;
EXTERN int thechar; extern int thechar;
EXTERN char* thestring; extern char* thestring;
extern LinkArch* thelinkarch; extern LinkArch* thelinkarch;
EXTERN Type* thisfn; EXTERN Type* thisfn;
EXTERN int32 thunk; EXTERN int32 thunk;
@ -524,6 +524,7 @@ EXTERN int flag_largemodel;
EXTERN int ncontin; EXTERN int ncontin;
EXTERN int canreach; EXTERN int canreach;
EXTERN int warnreach; EXTERN int warnreach;
EXTERN int nacl;
EXTERN Bits zbits; EXTERN Bits zbits;
EXTERN Fmt pragcgobuf; EXTERN Fmt pragcgobuf;
EXTERN Biobuf bstdout; EXTERN Biobuf bstdout;

View File

@ -117,6 +117,19 @@ void
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
int c; int c;
char *p;
// Allow GOARCH=thestring or GOARCH=thestringsuffix,
// but not other values.
p = getgoarch();
if(strncmp(p, thestring, strlen(thestring)) != 0)
sysfatal("cannot use %cc with GOARCH=%s", thechar, p);
if(strcmp(getgoarch(), "amd64p32") == 0) // must be before cinit
ewidth[TIND] = 4;
nacl = strcmp(getgoos(), "nacl") == 0;
if(nacl)
flag_largemodel = 1;
quotefmtinstall(); // before cinit, which overrides %Q quotefmtinstall(); // before cinit, which overrides %Q