(by rrh) Added three extra data types: GFLOAT, HFLOAT and OCTA
[unix-history] / usr / src / old / pcc / c2.vax / c21.c
index 84633f6..ac4f7c1 100644 (file)
@@ -1,5 +1,5 @@
-static char sccsid[] = "@(#)c21.c 4.1 %G%";
-/* char C21[] = {"@(#)c21.c 1.82 - 81 ??/??/?? ??:??:?? JFR"}; /* sccs ident */
+static char sccsid[] = "@(#)c21.c 4.8 %G%";
+/* char C21[] = {"@(#)c21.c 1.83 80/10/16 21:18:22 JFR"}; /* sccs ident */
 
 /*
  * C object code improver-- second part
 
 /*
  * C object code improver-- second part
@@ -12,7 +12,22 @@ static       char sccsid[] = "@(#)c21.c 4.1 %G%";
 #define NUSE 6
 int ioflag;
 int biti[NUSE] = {1,2,4,8,16,32};
 #define NUSE 6
 int ioflag;
 int biti[NUSE] = {1,2,4,8,16,32};
-int bitsize[4] = {0,8,16,32}; /* index by type codes */
+int bitsize[] = {      /* index by type codes */
+       0,              /* not allocated */
+       8,              /* BYTE */
+       16,             /* WORD */
+       32,             /* LONG */
+       32,             /* FFLOAT /
+       64,             /* DFLOAT */
+       64,             /* GFLOAT */
+       128,            /* HFLOAT */
+       64,             /* QUAD */
+       128,            /* OCTA */
+       0,              /* OP2 */
+       0,              /* OP3 */
+       0,              /* OPB */
+       0               /* OPX */
+};
 int pos,siz; long f; /* for bit field communication */
 struct node *uses[NUSE]; /* for backwards flow analysis */
 char *lastrand; /* last operand of instruction */
 int pos,siz; long f; /* for bit field communication */
 struct node *uses[NUSE]; /* for backwards flow analysis */
 char *lastrand; /* last operand of instruction */
@@ -68,7 +83,7 @@ bmove() {
                if ((p->subop&0xF)!=LONG) goto std; cp1=p->code;
                if (*cp1++!='$') goto std; splitrand(p);
                if (equstr(regs[RT2],"fp") && !indexa(regs[RT1])) {/* address comp. */
                if ((p->subop&0xF)!=LONG) goto std; cp1=p->code;
                if (*cp1++!='$') goto std; splitrand(p);
                if (equstr(regs[RT2],"fp") && !indexa(regs[RT1])) {/* address comp. */
-                       char buf[50]; cp2=buf; *cp2++='-'; 
+                       char buf[C2_ASIZE]; cp2=buf; *cp2++='-'; 
                        cp1=regs[RT1]+1; while (*cp2++= *cp1++); --cp2;
                        cp1="(fp),"; while (*cp2++= *cp1++); --cp2;
                        cp1=regs[RT3]; while (*cp2++= *cp1++);
                        cp1=regs[RT1]+1; while (*cp2++= *cp1++); --cp2;
                        cp1="(fp),"; while (*cp2++= *cp1++); --cp2;
                        cp1=regs[RT3]; while (*cp2++= *cp1++);
@@ -86,7 +101,7 @@ bmove() {
                        **      movl    r0,bar    /
                        */
                        register struct node    *pnext = p->forw;
                        **      movl    r0,bar    /
                        */
                        register struct node    *pnext = p->forw;
-                       char    buf[50];
+                       char    buf[C2_ASIZE];
 
                        if (pnext->op == MOV && pnext->subop == LONG)
                        {
 
                        if (pnext->op == MOV && pnext->subop == LONG)
                        {
@@ -419,11 +434,11 @@ mov:
                r = isreg(regs[RT1]);
                r1 = isreg(regs[RT2]);
                dest(regs[RT2],p->subop);
                r = isreg(regs[RT1]);
                r1 = isreg(regs[RT2]);
                dest(regs[RT2],p->subop);
-               if (r>=0) {
-                       if (r1>=0) savereg(r1, regs[r]+1, p->subop);
-                       else if (p->op!=CVT) savereg(r, regs[RT2], p->subop);
-               } else if (r1>=0) savereg(r1, regs[RT1], p->subop);
-               else if (p->op!=CVT) setcon(regs[RT1], regs[RT2], p->subop);
+               if (r>=0) {
+                       if (r1>=0) savereg(r1, regs[r]+1, p->subop);
+                       else if (p->op!=CVT) savereg(r, regs[RT2], p->subop);
+               } else if (r1>=0) savereg(r1, regs[RT1], p->subop);
+               else if (p->op!=CVT) setcon(regs[RT1], regs[RT2], p->subop);
                break;
 
 /* .rx,.wx */
                break;
 
 /* .rx,.wx */
@@ -489,8 +504,9 @@ mov:
        case BIT:
                splitrand(p);
                /* fool repladdr into doing right number of operands */
        case BIT:
                splitrand(p);
                /* fool repladdr into doing right number of operands */
-               if (p->op==CASE || p->op==MOVC3 || p->op==PROBER || p->op==PROBEW)
-                       lastrand=regs[RT4];
+               if (p->op==CASE || p->op==PROBER || p->op==PROBEW) lastrand=regs[RT4];
+/*             else if (p->op==CMPV || p->op==CMPZV) lastrand=regs[RT4+1]; */
+               else if (p->op==MOVC3) lastrand=regs[RT1];
                else lastrand=regs[RT3];
                repladdr(p);
                if (p->op==CALLS || p->op==MOVC3) clearreg();
                else lastrand=regs[RT3];
                repladdr(p);
                if (p->op==CALLS || p->op==MOVC3) clearreg();
@@ -577,7 +593,7 @@ register struct node *p;
                } else if (p->op==MOV && p->forw->op!=EXTV && p->forw->op!=EXTZV) {
                        /* superfluous fetch */
                        int nmatch;
                } else if (p->op==MOV && p->forw->op!=EXTV && p->forw->op!=EXTZV) {
                        /* superfluous fetch */
                        int nmatch;
-                       char src[20];
+                       char src[C2_ASIZE];
        movit:
                        cp2=src; cp1=regs[RT1]; while (*cp2++= *cp1++);
                        splitrand(p->forw);
        movit:
                        cp2=src; cp1=regs[RT1]; while (*cp2++= *cp1++);
                        splitrand(p->forw);
@@ -614,8 +630,9 @@ register struct node *p;
        || OP2==(p->subop>>4) && 0<=(r=isreg(regs[RT2])) && r<NUSE && uses[r]==0) {
                /* writing a dead register is useless, but watch side effects */
                switch (p->op) {
        || OP2==(p->subop>>4) && 0<=(r=isreg(regs[RT2])) && r<NUSE && uses[r]==0) {
                /* writing a dead register is useless, but watch side effects */
                switch (p->op) {
+               case ACB:
                case AOBLEQ: case AOBLSS: case SOBGTR: case SOBGEQ: break;
                case AOBLEQ: case AOBLSS: case SOBGTR: case SOBGEQ: break;
-               default: if (p->op==ACB) break;
+               default:
                        if (uses[r]==0) {/* no direct uses, check for use of condition codes */
                                register struct node *q=p;
                                while ((q=nonlab(q->forw))->combop==JBR) q=q->ref;      /* cc unused, unchanged */
                        if (uses[r]==0) {/* no direct uses, check for use of condition codes */
                                register struct node *q=p;
                                while ((q=nonlab(q->forw))->combop==JBR) q=q->ref;      /* cc unused, unchanged */
@@ -644,6 +661,7 @@ register struct node *p;
                /* check for  r  */
                if (lastrand!=cp1 && 0<=(r=isreg(cp1)) && r<NUSE && uses[r]==0) {
                        uses[r]=p; cp2=regs[r]; *cp2++=p->subop;
                /* check for  r  */
                if (lastrand!=cp1 && 0<=(r=isreg(cp1)) && r<NUSE && uses[r]==0) {
                        uses[r]=p; cp2=regs[r]; *cp2++=p->subop;
+                       if (p->op==ASH && preg==(regs+RT1+1)) cp2[-1]=BYTE; /* stupid DEC */
                        if (p->op==MOV || p->op==PUSH || p->op==CVT || p->op==MOVZ || p->op==COM || p->op==NEG) {
                                if (p->op==PUSH) cp1="-(sp)";
                                else {
                        if (p->op==MOV || p->op==PUSH || p->op==CVT || p->op==MOVZ || p->op==COM || p->op==NEG) {
                                if (p->op==PUSH) cp1="-(sp)";
                                else {
@@ -654,7 +672,8 @@ register struct node *p;
                                        if (p->op!=MOV) cp1=0;
                                }
                                if (cp1) while (*cp2++= *cp1++);
                                        if (p->op!=MOV) cp1=0;
                                }
                                if (cp1) while (*cp2++= *cp1++);
-                       } else *cp2++=0;
+                               else *cp2=0;
+                       } else *cp2=0;
                        continue;
                }
                /* check for (r),(r)+,-(r),[r] */
                        continue;
                }
                /* check for (r),(r)+,-(r),[r] */
@@ -769,7 +788,7 @@ bicopt(p) register struct node *p; {
 /* use field operations or MOVZ if possible.  done as part of 'bflow'.
 */
        register char *cp1,*cp2; int r;
 /* use field operations or MOVZ if possible.  done as part of 'bflow'.
 */
        register char *cp1,*cp2; int r;
-       char src[50];
+       char src[C2_ASIZE];
        if (!bixprep(p,JBCC)) return(p);
        if (f==0) {/* the BIC isolates low order bits */
                siz=pos; pos=0;
        if (!bixprep(p,JBCC)) return(p);
        if (f==0) {/* the BIC isolates low order bits */
                siz=pos; pos=0;
@@ -862,7 +881,7 @@ addsob()
 
        for (p = &first; (p1 = p->forw)!=0; p = p1) {
        if (p->combop==T(DEC,LONG) && p1->op==CBR) {
 
        for (p = &first; (p1 = p->forw)!=0; p = p1) {
        if (p->combop==T(DEC,LONG) && p1->op==CBR) {
-               if (abs(p->seq - p1->ref->seq) > 12) continue;
+               if (abs(p->seq - p1->ref->seq) > 8) continue;
                if (p1->subop==JGE || p1->subop==JGT) {
                        if (p1->subop==JGE) p->combop=SOBGEQ; else p->combop=SOBGTR;
                        p->pop=0;
                if (p1->subop==JGE || p1->subop==JGT) {
                        if (p1->subop==JGE) p->combop=SOBGEQ; else p->combop=SOBGTR;
                        p->pop=0;
@@ -887,7 +906,7 @@ addsob()
                if (p1->combop==T(CMP,LONG) && (p2=p1->forw)->op==CBR) {
                        register char *cp1,*cp2;
                        splitrand(p1); if (!equstr(p->code,regs[RT1])) continue;
                if (p1->combop==T(CMP,LONG) && (p2=p1->forw)->op==CBR) {
                        register char *cp1,*cp2;
                        splitrand(p1); if (!equstr(p->code,regs[RT1])) continue;
-                       if (abs(p->seq - p2->ref->seq)>12) {/* outside byte displ range */
+                       if (abs(p->seq - p2->ref->seq)>8) {/* outside byte displ range */
                                if (p2->subop!=JLE) continue;
                                p->combop=T(ACB,LONG);
                                cp2=regs[RT1]; cp1=regs[RT2]; while (*cp2++= *cp1++); /* limit */
                                if (p2->subop!=JLE) continue;
                                p->combop=T(ACB,LONG);
                                cp2=regs[RT1]; cp1=regs[RT2]; while (*cp2++= *cp1++); /* limit */
@@ -995,8 +1014,34 @@ register char *s;
        source(s); /* handle addressing side effects */
        if ((i = isreg(s)) >= 0) {
                *(short *)(regs[i]) = 0; /* if register destination, that reg is a goner */
        source(s); /* handle addressing side effects */
        if ((i = isreg(s)) >= 0) {
                *(short *)(regs[i]) = 0; /* if register destination, that reg is a goner */
-               if (DOUBLE==(type&0xF) || DOUBLE==((type>>4)&0xF))
-                       *(short *)(regs[i+1]) = 0; /* clobber two at once */
+               switch(type & 0xF){
+               case DFLOAT:    /* clobber two at once */
+                       /*FALLTHROUGH*/
+               case GFLOAT:
+                       *(short *)(regs[i+1]) = 0;
+                       break;
+               case HFLOAT:    /* clobber four at once */
+                       *(short *)(regs[i+1]) = 0;
+                       *(short *)(regs[i+2]) = 0;
+                       *(short *)(regs[i+3]) = 0;
+                       break;
+               }
+               switch((type>>4)&0xF){
+               case DFLOAT:    /* clobber two at once */
+                       /*FALLTHROUGH*/
+               case GFLOAT:
+                       *(short *)(regs[i+1]) = 0;
+                       break;
+               case HFLOAT:    /* clobber four at once */
+                       *(short *)(regs[i+1]) = 0;
+                       *(short *)(regs[i+2]) = 0;
+                       *(short *)(regs[i+3]) = 0;
+                       break;
+               }
+               /*
+               if (DFLOAT==(type&0xF) || DFLOAT==((type>>4)&0xF))
+                       *(short *)(regs[i+1]) = 0;
+               */
        }
        for (i=NREG; --i>=0;)
                if (regs[i][1]=='*' && equstr(s, regs[i]+2))
        }
        for (i=NREG; --i>=0;)
                if (regs[i][1]=='*' && equstr(s, regs[i]+2))
@@ -1025,9 +1070,9 @@ compat(have, want) {
 register int hsrc, hdst;
 if (0==(want &= 0xF)) return(1); /* anything satisfies a wildcard want */
 hsrc=have&0xF; if (0==(hdst=((have>>4)&0xF)) || hdst>=OP2) hdst=hsrc;
 register int hsrc, hdst;
 if (0==(want &= 0xF)) return(1); /* anything satisfies a wildcard want */
 hsrc=have&0xF; if (0==(hdst=((have>>4)&0xF)) || hdst>=OP2) hdst=hsrc;
-if (want>=FLOAT) return(hdst==want && hsrc==want);
-       /* FLOAT, DOUBLE not compat: rounding */
-return(hsrc>=want && hdst>=want && hdst<FLOAT);
+if (want>=FFLOAT) return(hdst==want && hsrc==want);
+       /* FLOAT, DFLOAT not compat: rounding */
+return(hsrc>=want && hdst>=want && hdst<FFLOAT);
 }
 
 equtype(t1,t2) {return(compat(t1,t2) && compat(t2,t1));}
 }
 
 equtype(t1,t2) {return(compat(t1,t2) && compat(t2,t1));}