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:
parent
77ac8ecbeb
commit
7954b2b90b
@ -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++) {
|
||||||
|
@ -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");
|
||||||
|
@ -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();
|
||||||
|
@ -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++) {
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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++) {
|
||||||
|
@ -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");
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user