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();
                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++) {
 
 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");
 
 
 LinkArch       *thelinkarch = &linkarm;
 
+int thechar = '5';
+char *thestring = "arm";
+
 void
 ginit(void)
 {
        Type *t;
 
-       thechar = '5';
-       thestring = "arm";
        exregoffset = REGEXT;
        exfregoffset = FREGEXT;
        listinit();
 
        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();
                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++) {
 
                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;
 {
 
        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;
 
                                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;
 
        }
        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");
                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;
 
        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;
        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;
 
 
 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;
                if(i >= D_X0 && i <= D_X7)
                        reg[i] = 0;
        }
+       if(nacl) {
+               reg[D_BP] = 1;
+               reg[D_R15] = 1;
+       }
 }
 
 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);
                }
                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);
 
        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,
                goto ld;
        case TIND:
                a = AMOVQ;
+               if(ewidth[TIND] == 4)
+                       a = AMOVL;
 
        ld:
                regalloc(&nod, f, 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]);
                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;
 
        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();
                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++) {
 
        }
        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");
 
 
 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();
 
 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;
 EXTERN int     ncontin;
 EXTERN int     canreach;
 EXTERN int     warnreach;
+EXTERN int     nacl;
 EXTERN Bits    zbits;
 EXTERN Fmt     pragcgobuf;
 EXTERN Biobuf  bstdout;
 
 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