diff options
Diffstat (limited to 'utils/5c')
| -rw-r--r-- | utils/5c/5.out.h | 16 | ||||
| -rw-r--r-- | utils/5c/enam.c | 6 | ||||
| -rw-r--r-- | utils/5c/gc.h | 11 | ||||
| -rw-r--r-- | utils/5c/list.c | 2 | ||||
| -rw-r--r-- | utils/5c/peep.c | 5 | ||||
| -rw-r--r-- | utils/5c/reg.c | 4 | ||||
| -rw-r--r-- | utils/5c/swt.c | 39 | ||||
| -rw-r--r-- | utils/5c/txt.c | 87 |
8 files changed, 112 insertions, 58 deletions
diff --git a/utils/5c/5.out.h b/utils/5c/5.out.h index dad2c336..a618f8f1 100644 --- a/utils/5c/5.out.h +++ b/utils/5c/5.out.h @@ -25,6 +25,7 @@ #define NFREG 8 #define FREGRET 0 #define FREGEXT 7 +#define FREGTMP 15 /* compiler allocates register variables F0 up */ /* compiler allocates external registers F7 down */ @@ -92,6 +93,8 @@ enum as AMULD, ADIVF, ADIVD, +// ASQRTF, +// ASQRTD, ASRL, ASRA, @@ -143,6 +146,16 @@ enum as ASIGNAME, + /* moved here to preserve values of older identifiers */ + ASQRTF, + ASQRTD, + + ALDREX, + ASTREX, + + ALDREXD, + ASTREXD, + ALAST, }; @@ -173,7 +186,8 @@ enum as #define D_SHIFT (D_NONE+19) #define D_FPCR (D_NONE+20) -#define D_REGREG (D_NONE+21) +#define D_REGREG (D_NONE+21) +#define D_ADDR (D_NONE+22) /* name */ #define D_EXTERN (D_NONE+3) diff --git a/utils/5c/enam.c b/utils/5c/enam.c index 989b2760..e5ea0b84 100644 --- a/utils/5c/enam.c +++ b/utils/5c/enam.c @@ -94,5 +94,11 @@ char* anames[] = "BXRET", "DWORD", "SIGNAME", + "SQRTF", + "SQRTD", + "LDREX", + "STREX", + "LDREXD", + "STREXD", "LAST", }; diff --git a/utils/5c/gc.h b/utils/5c/gc.h index fa93cd0a..b9382a00 100644 --- a/utils/5c/gc.h +++ b/utils/5c/gc.h @@ -3,7 +3,7 @@ /* * 5c/arm - * Arm 7500 + * Arm */ #define SZ_CHAR 1 #define SZ_SHORT 2 @@ -59,7 +59,7 @@ struct Prog struct Case { Case* link; - long val; + vlong val; long label; char def; char isv; @@ -68,7 +68,7 @@ struct Case struct C1 { - long val; + vlong val; long label; }; @@ -265,7 +265,7 @@ void gpseudo(int, Sym*, Node*); /* * swt.c */ -int swcmp(const void*, const void*); +int swcmp(void*, void*); void doswit(Node*); void swit1(C1*, int, long, Node*); void swit2(C1*, int, long, Node*, Node*); @@ -276,7 +276,6 @@ long outstring(char*, long); int mulcon(Node*, Node*); Multab* mulcon0(long); void nullwarn(Node*, Node*); -void sextern(Sym*, Node*, long, long); void gextern(Sym*, Node*, long, long); void outcode(void); void ieeedtod(Ieee*, double); @@ -297,7 +296,7 @@ int Rconv(Fmt*); * reg.c */ Reg* rega(void); -int rcmp(const void*, const void*); +int rcmp(void*, void*); void regopt(Prog*); void addmove(Reg*, int, int, int); Bits mkvar(Adr*, int); diff --git a/utils/5c/list.c b/utils/5c/list.c index d50f07db..c7276dd8 100644 --- a/utils/5c/list.c +++ b/utils/5c/list.c @@ -98,7 +98,7 @@ Aconv(Fmt *fp) int a; a = va_arg(fp->args, int); - s = "???"; + s = "?"; if(a >= AXXX && a < ALAST) s = anames[a]; return fmtstrcpy(fp, s); diff --git a/utils/5c/peep.c b/utils/5c/peep.c index 25e5a118..9d4a2da2 100644 --- a/utils/5c/peep.c +++ b/utils/5c/peep.c @@ -1069,7 +1069,7 @@ copyu(Prog *p, Adr *v, Adr *s) if(v->type == D_REG) { if(v->reg <= REGEXT && v->reg > exregoffset) return 2; - if(v->reg == REGARG) + if(v->reg == (uchar)REGARG) return 2; } if(v->type == D_FREG) @@ -1087,11 +1087,10 @@ copyu(Prog *p, Adr *v, Adr *s) case ATEXT: /* funny */ if(v->type == D_REG) - if(v->reg == REGARG) + if(v->reg == (uchar)REGARG) return 3; return 0; } - /* not reached */ } int diff --git a/utils/5c/reg.c b/utils/5c/reg.c index 43c78712..ab1005ba 100644 --- a/utils/5c/reg.c +++ b/utils/5c/reg.c @@ -18,7 +18,7 @@ rega(void) } int -rcmp(const void *a1, const void *a2) +rcmp(void *a1, void *a2) { Rgn *p1, *p2; int c1, c2; @@ -1125,7 +1125,7 @@ RtoB(int r) int BtoR(long b) { - b &= 0x01fcL; + b &= 0x01fcL; // excluded R9 and R10 for extern registers if(b == 0) return 0; return bitno(b); diff --git a/utils/5c/swt.c b/utils/5c/swt.c index ccc63ee7..6e0b8d51 100644 --- a/utils/5c/swt.c +++ b/utils/5c/swt.c @@ -25,8 +25,8 @@ swit2(C1 *q, int nc, long def, Node *n, Node *tn) } if(nc < 5) { for(i=0; i<nc; i++) { - if(debug['W']) - print("case = %.8lux\n", q->val); + if(debug['K']) + print("case = %.8llux\n", q->val); gopcode(OEQ, nodconst(q->val), n, Z); patch(p, q->label); q++; @@ -38,16 +38,16 @@ swit2(C1 *q, int nc, long def, Node *n, Node *tn) i = nc / 2; r = q+i; - if(debug['W']) - print("case > %.8lux\n", r->val); + if(debug['K']) + print("case > %.8llux\n", r->val); gopcode(OGT, nodconst(r->val), n, Z); sp = p; gopcode(OEQ, nodconst(r->val), n, Z); /* just gen the B.EQ */ patch(p, r->label); swit2(q, i, def, n, tn); - if(debug['W']) - print("case < %.8lux\n", r->val); + if(debug['K']) + print("case < %.8llux\n", r->val); patch(sp, pc); swit2(r+1, nc-i-1, def, n, tn); return; @@ -59,8 +59,8 @@ direct: gopcode(OCASE, nodconst((q+nc-1)->val - v), n, Z); patch(p, def); for(i=0; i<nc; i++) { - if(debug['W']) - print("case = %.8lux\n", q->val); + if(debug['K']) + print("case = %.8llux\n", q->val); while(q->val != v) { nextpc(); p->as = ABCASE; @@ -269,23 +269,6 @@ loop: } void -sextern(Sym *s, Node *a, long o, long w) -{ - long e, lw; - - for(e=0; e<w; e+=NSNAME) { - lw = NSNAME; - if(w-e < lw) - lw = w-e; - gpseudo(ADATA, s, nodconst(0)); - p->from.offset += o+e; - p->reg = lw; - p->to.type = D_SCONST; - memmove(p->to.sval, a->cstring+e, lw); - } -} - -void gextern(Sym *s, Node *a, long o, long w) { @@ -579,7 +562,7 @@ align(long i, Type *t, int op) w = packflg; break; - case Ael1: /* initial allign of struct element */ + case Ael1: /* initial align of struct element */ for(v=t; v->etype==TARRAY; v=v->link) ; w = ewidth[v->etype]; @@ -600,7 +583,7 @@ align(long i, Type *t, int op) } break; - case Aarg1: /* initial allign of parameter */ + case Aarg1: /* initial align of parameter */ w = ewidth[t->etype]; if(w <= 0 || w >= SZ_LONG) { w = SZ_LONG; @@ -614,7 +597,7 @@ align(long i, Type *t, int op) w = SZ_LONG; break; - case Aaut3: /* total allign of automatic */ + case Aaut3: /* total align of automatic */ o = align(o, t, Ael2); o = align(o, t, Ael1); w = SZ_LONG; /* because of a pun in cc/dcl.c:contig() */ diff --git a/utils/5c/txt.c b/utils/5c/txt.c index f97eb61a..fadf5938 100644 --- a/utils/5c/txt.c +++ b/utils/5c/txt.c @@ -1,5 +1,7 @@ #include "gc.h" +static char resvreg[nelem(reg)]; + void ginit(void) { @@ -80,6 +82,16 @@ ginit(void) com64init(); memset(reg, 0, sizeof(reg)); + /* don't allocate */ + reg[REGTMP] = 1; + reg[REGSB] = 1; + reg[REGSP] = 1; + reg[REGLINK] = 1; + reg[REGPC] = 1; + /* keep two external registers */ + reg[REGEXT] = 1; + reg[REGEXT-1] = 1; + memmove(resvreg, reg, sizeof(reg)); } void @@ -89,10 +101,10 @@ gclean(void) Sym *s; for(i=0; i<NREG; i++) - if(reg[i]) + if(reg[i] && !resvreg[i]) diag(Z, "reg %d left allocated", i); for(i=NREG; i<NREG+NFREG; i++) - if(reg[i]) + if(reg[i] && !resvreg[i]) diag(Z, "freg %d left allocated", i-NREG); while(mnstring) outstring("", 1L); @@ -283,7 +295,7 @@ regalloc(Node *n, Node *tn, Node *o) for(i=REGRET+1; i<NREG; i++) { if(j >= NREG) j = REGRET+1; - if(reg[j] == 0) { + if(reg[j] == 0 && resvreg[j] == 0) { i = j; goto out; } @@ -319,7 +331,7 @@ err: return; out: reg[i]++; -/* lasti++; *** StrongARM does register forwarding */ + lasti++; if(lasti >= 5) lasti = 0; nodreg(n, tn, i); @@ -549,7 +561,8 @@ void gmove(Node *f, Node *t) { int ft, tt, a; - Node nod; + Node nod, nod1; + Prog *p1; ft = f->type->etype; tt = t->type->etype; @@ -678,21 +691,58 @@ gmove(Node *f, Node *t) } break; case TUINT: - case TINT: case TULONG: + if(tt == TFLOAT || tt == TDOUBLE) { + // ugly and probably longer than necessary, + // but vfp has a single instruction for this, + // so hopefully it won't last long. + // + // tmp = f + // tmp1 = tmp & 0x80000000 + // tmp ^= tmp1 + // t = float(int32(tmp)) + // if(tmp1) + // t += 2147483648. + // + regalloc(&nod, f, Z); + regalloc(&nod1, f, Z); + gins(AMOVW, f, &nod); + gins(AMOVW, &nod, &nod1); + gins(AAND, nodconst(0x80000000), &nod1); + gins(AEOR, &nod1, &nod); + if(tt == TFLOAT) + gins(AMOVWF, &nod, t); + else + gins(AMOVWD, &nod, t); + gins(ACMP, nodconst(0), Z); + raddr(&nod1, p); + gins(ABEQ, Z, Z); + regfree(&nod); + regfree(&nod1); + p1 = p; + regalloc(&nod, t, Z); + if(tt == TFLOAT) { + gins(AMOVF, nodfconst(2147483648.), &nod); + gins(AADDF, &nod, t); + } else { + gins(AMOVD, nodfconst(2147483648.), &nod); + gins(AADDD, &nod, t); + } + regfree(&nod); + patch(p1, pc); + return; + } + // fall through + + case TINT: case TLONG: case TIND: switch(tt) { case TDOUBLE: - case TVLONG: gins(AMOVWD, f, t); - if(ft == TULONG) { - } return; case TFLOAT: gins(AMOVWF, f, t); - if(ft == TULONG) { - } return; case TINT: case TUINT: @@ -710,7 +760,6 @@ gmove(Node *f, Node *t) case TSHORT: switch(tt) { case TDOUBLE: - case TVLONG: regalloc(&nod, f, Z); gins(AMOVH, f, &nod); gins(AMOVWD, &nod, t); @@ -740,7 +789,6 @@ gmove(Node *f, Node *t) case TUSHORT: switch(tt) { case TDOUBLE: - case TVLONG: regalloc(&nod, f, Z); gins(AMOVHU, f, &nod); gins(AMOVWD, &nod, t); @@ -770,7 +818,6 @@ gmove(Node *f, Node *t) case TCHAR: switch(tt) { case TDOUBLE: - case TVLONG: regalloc(&nod, f, Z); gins(AMOVB, f, &nod); gins(AMOVWD, &nod, t); @@ -800,7 +847,6 @@ gmove(Node *f, Node *t) case TUCHAR: switch(tt) { case TDOUBLE: - case TVLONG: regalloc(&nod, f, Z); gins(AMOVBU, f, &nod); gins(AMOVWD, &nod, t); @@ -1015,7 +1061,8 @@ gopcode(int o, Node *f1, Node *f2, Node *t) nextpc(); p->as = a; naddr(f1, &p->from); - if(a == ACMP && f1->op == OCONST && p->from.offset < 0) { + if(a == ACMP && f1->op == OCONST && p->from.offset < 0 && + p->from.offset != 0x80000000) { p->as = ACMN; p->from.offset = -p->from.offset; } @@ -1185,9 +1232,12 @@ exreg(Type *t) long o; if(typechlp[t->etype]) { - if(exregoffset <= REGEXT-4) + if(exregoffset <= REGEXT-2) return 0; o = exregoffset; + if(reg[o] && !resvreg[o]) + return 0; + resvreg[o] = reg[o] = 1; exregoffset--; return o; } @@ -1195,6 +1245,9 @@ exreg(Type *t) if(exfregoffset <= NFREG-1) return 0; o = exfregoffset + NREG; + if(reg[o] && !resvreg[o]) + return 0; + resvreg[o] = reg[o] = 1; exfregoffset--; return o; } |
