--- /sys/src/cmd/5c/5.out.h +++ /sys/src/cmd/5c/5.out.h @@ -93,8 +93,6 @@ enum as AMULD, ADIVF, ADIVD, -// ASQRTF, -// ASQRTD, ASRL, ASRA, @@ -146,7 +144,6 @@ enum as ASIGNAME, - /* moved here to preserve values of older identifiers */ ASQRTF, ASQRTD, @@ -156,6 +153,54 @@ enum as ALDREXD, ASTREXD, + AERET, + AWFE, + AWFI, + + ACPS, + ACPSID, + ACPSIE, + + ADMB, + ADSB, + AISB, + + ACLZ, + + ACLREX, + ALDREXB, + ASTREXB, + ALDREXH, + ASTREXH, + + AABSF, + AABSD, + ANEGF, + ANEGD, + + AMLAF, + AMLAD, + AMLSF, + AMLSD, + ANMULF, + ANMULD, + ANMLAF, + ANMLAD, + ANMLSF, + ANMLSD, + + AMOVWFU, + AMOVWDU, + AMOVFWU, + AMOVDWU, + + AMOVMF, + AMOVMD, + APOPF, + APOPD, + APUSHF, + APUSHD, + ALAST, }; @@ -179,7 +224,7 @@ enum as #define D_SCONST (D_NONE+9) #define D_PSR (D_NONE+10) #define D_REG (D_NONE+12) -#define D_FREG (D_NONE+13) +#define D_FREG (D_NONE+13) /* Fn = S(2*n) or Dn depending on op */ #define D_FILE (D_NONE+16) #define D_OCONST (D_NONE+17) #define D_FILE1 (D_NONE+18) @@ -188,6 +233,9 @@ enum as #define D_FPCR (D_NONE+20) #define D_REGREG (D_NONE+21) #define D_ADDR (D_NONE+22) +#define D_VFPCR (D_NONE+23) +#define D_SFREG (D_NONE+24) /* single-precision register Sn */ +#define D_QREG (D_NONE+25) /* name */ #define D_EXTERN (D_NONE+3) --- /sys/src/cmd/5c/cgen.c +++ /sys/src/cmd/5c/cgen.c @@ -1,5 +1,7 @@ #include "gc.h" +static void genasop(int, Node*, Node*, Node *); + void cgen(Node *n, Node *nn) { @@ -54,7 +56,7 @@ cgenrel(Node *n, Node *nn, int inrel) cgen(r, &nod); regsalloc(&nod1, r); - gopcode(OAS, &nod, Z, &nod1); + gmove(&nod, &nod1); regfree(&nod); nod = *n; @@ -244,7 +246,7 @@ cgenrel(Node *n, Node *nn, int inrel) reglcgen(&nod2, l, Z); else nod2 = *l; - regalloc(&nod, r, nn); + regalloc(&nod, l, nn); gopcode(OAS, &nod2, Z, &nod); gopcode(o, r, Z, &nod); gopcode(OAS, &nod, Z, &nod2); @@ -254,6 +256,8 @@ cgenrel(Node *n, Node *nn, int inrel) regfree(&nod2); break; } + genasop(o, l, r, nn); + break; case OASLMUL: case OASLDIV: @@ -263,32 +267,7 @@ cgenrel(Node *n, Node *nn, int inrel) case OASMOD: if(l->op == OBIT) goto asbitop; - if(l->complex >= r->complex) { - if(l->addable < INDEXED) - reglcgen(&nod2, l, Z); - else - nod2 = *l; - regalloc(&nod1, r, Z); - cgen(r, &nod1); - } else { - regalloc(&nod1, r, Z); - cgen(r, &nod1); - if(l->addable < INDEXED) - reglcgen(&nod2, l, Z); - else - nod2 = *l; - } - - regalloc(&nod, n, nn); - gmove(&nod2, &nod); - gopcode(o, &nod1, Z, &nod); - gmove(&nod, &nod2); - if(nn != Z) - gopcode(OAS, &nod, Z, nn); - regfree(&nod); - regfree(&nod1); - if(l->addable < INDEXED) - regfree(&nod2); + genasop(o, l, r, nn); break; asbitop: @@ -319,6 +298,7 @@ cgenrel(Node *n, Node *nn, int inrel) break; case OFUNC: + l = uncomma(l); if(l->complex >= FNX) { if(l->op != OIND) diag(n, "bad function call"); @@ -564,6 +544,43 @@ cgenrel(Node *n, Node *nn, int inrel) return; } +static void +genasop(int o, Node *l, Node *r, Node *nn) +{ + Node nod, nod1, nod2; + int hardleft; + + hardleft = l->addable < INDEXED || l->complex >= FNX; + if(l->complex >= r->complex) { + if(hardleft) + reglcgen(&nod2, l, Z); + else + nod2 = *l; + regalloc(&nod1, r, Z); + cgen(r, &nod1); + } else { + regalloc(&nod1, r, Z); + cgen(r, &nod1); + if(hardleft) + reglcgen(&nod2, l, Z); + else + nod2 = *l; + } + if(nod1.type == nod2.type || !typefd[nod1.type->etype]) + regalloc(&nod, &nod2, nn); + else + regalloc(&nod, &nod1, Z); + gmove(&nod2, &nod); + gopcode(o, &nod1, Z, &nod); + gmove(&nod, &nod2); + if(nn != Z) + gmove(&nod2, nn); + regfree(&nod); + regfree(&nod1); + if(hardleft) + regfree(&nod2); +} + void reglcgen(Node *t, Node *n, Node *nn) { @@ -915,12 +932,12 @@ sugen(Node *n, Node *nn, long w) case OSTRUCT: /* - * rewrite so lhs has no fn call + * rewrite so lhs has no side effects */ - if(nn != Z && nn->complex >= FNX) { + if(nn != Z && side(nn)) { nod1 = *n; nod1.type = typ(TIND, n->type); - regret(&nod2, &nod1); + regalloc(&nod2, &nod1, Z); lcgen(nn, &nod2); regsalloc(&nod0, &nod1); gopcode(OAS, &nod2, Z, &nod0); @@ -999,6 +1016,7 @@ sugen(Node *n, Node *nn, long w) break; case OFUNC: + /* this transformation should probably be done earlier */ if(nn == Z) { sugen(n, nodrat, w); break; @@ -1010,6 +1028,7 @@ sugen(Node *n, Node *nn, long w) } else nn = nn->left; n = new(OFUNC, n->left, new(OLIST, nn, n->right)); + n->complex = FNX; n->type = types[TVOID]; n->left->type = types[TVOID]; cgen(n, Z); --- /sys/src/cmd/5c/gc.h +++ /sys/src/cmd/5c/gc.h @@ -51,8 +51,9 @@ struct Prog Adr to; Prog* link; long lineno; - char as; + uchar as; char reg; + char reghi; /* for long multiply, double loads */ uchar scond; }; #define P ((Prog*)0) @@ -126,7 +127,7 @@ struct Reg }; #define R ((Reg*)0) -#define NRGN 1000 /* was 600; raised for paranoia.c */ +#define NRGN 1000 struct Rgn { Reg* enter; @@ -173,6 +174,8 @@ EXTERN int suppress; #define bset(a,n) ((a).b[(n)/32]&(1L<<(n)%32)) +#define isbigendian() align(0, types[TCHAR], Aarg1) + #define CLOAD 4 #define CREF 5 #define CINF 1000 @@ -344,6 +347,7 @@ int predicable(Prog *p); int modifiescpsr(Prog *p); #pragma varargck type "A" int +#pragma varargck type "A" uint #pragma varargck type "B" Bits #pragma varargck type "D" Adr* #pragma varargck type "N" Adr* --- /sys/src/cmd/5c/list.c +++ /sys/src/cmd/5c/list.c @@ -84,7 +84,10 @@ Pconv(Fmt *fp) if(p->reg == NREG) snprint(str, sizeof(str), " %A%s %D,%D", a, sc, &p->from, &p->to); else - if(p->from.type != D_FREG) + if(p->reghi != NREG) + snprint(str, sizeof(str), " %A%s %D,R%d,%D,R%d", a, sc, &p->from, p->reg, &p->to, p->reghi); + else + if(p->from.type != D_FREG && p->from.type != D_SFREG && p->from.type != D_FCONST) snprint(str, sizeof(str), " %A%s %D,R%d,%D", a, sc, &p->from, p->reg, &p->to); else snprint(str, sizeof(str), " %A%s %D,F%d,%D", a, sc, &p->from, p->reg, &p->to); @@ -162,6 +165,18 @@ Dconv(Fmt *fp) snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg); break; + case D_SFREG: + snprint(str, sizeof(str), "S%d", a->reg); + if(a->name != D_NONE || a->sym != S) + snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg); + break; + + case D_QREG: + snprint(str, sizeof(str), "Q%d", a->reg); + if(a->name != D_NONE || a->sym != S) + snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg); + break; + case D_PSR: snprint(str, sizeof(str), "PSR"); if(a->name != D_NONE || a->sym != S) --- /sys/src/cmd/5c/peep.c +++ /sys/src/cmd/5c/peep.c @@ -306,6 +306,7 @@ subprop(Reg *r0) case AAND: case AEOR: case AMUL: + case AMULU: case ADIV: case ADIVU: @@ -977,6 +978,7 @@ copyu(Prog *p, Adr *v, Adr *s) case AAND: case AEOR: case AMUL: + case AMULU: case ADIV: case ADIVU: case AADDF: @@ -1112,6 +1114,7 @@ a2type(Prog *p) case AAND: case AEOR: case AMUL: + case AMULU: case ADIV: case ADIVU: return D_REG;