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();
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);
memset(debug, 0, sizeof(debug));
cinit();
@ -162,7 +168,7 @@ assemble(char *file)
errorexit();
}
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");
for(pass = 1; pass <= 2; pass++) {

View file

@ -354,7 +354,7 @@ gextern(Sym *s, Node *a, int32 o, int32 w)
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) {
Bprint(&outbuf, "\n");
Bprint(&outbuf, "$$ // exports\n\n");

View file

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

View file

@ -79,6 +79,12 @@ main(int argc, char *argv[])
listinit6();
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);
memset(debug, 0, sizeof(debug));
cinit();
@ -164,7 +170,7 @@ assemble(char *file)
errorexit();
}
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");
for(pass = 1; pass <= 2; pass++) {

View file

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

View file

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

View file

@ -228,7 +228,7 @@ outcode(void)
}
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) {
Bprint(&b, "\n");
Bprint(&b, "$$ // exports\n\n");
@ -292,6 +292,21 @@ align(int32 i, Type *t, int op, int32 *maxalign)
break;
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];
if(w <= 0 || 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 */
o += t->width;
if(ewidth[TIND] == 4) {
o = align(o, t, Aarg1, maxalign);
goto out;
}
w = t->width;
if(w > SZ_VLONG)
w = SZ_VLONG;
@ -315,6 +334,7 @@ align(int32 i, Type *t, int op, int32 *maxalign)
o = xround(o, w);
if(maxalign && *maxalign < w)
*maxalign = w;
out:
if(debug['A'])
print("align %s %d %T = %d\n", bnames[op], i, t, o);
return o;

View file

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

View file

@ -79,6 +79,12 @@ main(int argc, char *argv[])
listinit8();
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);
memset(debug, 0, sizeof(debug));
cinit();
@ -163,7 +169,7 @@ assemble(char *file)
errorexit();
}
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");
for(pass = 1; pass <= 2; pass++) {

View file

@ -233,7 +233,7 @@ outcode(void)
}
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) {
Bprint(&b, "\n");
Bprint(&b, "$$ // exports\n\n");

View file

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

View file

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

View file

@ -117,6 +117,19 @@ void
main(int argc, char *argv[])
{
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