Initial revision
authorceriel <none@none>
Mon, 24 Nov 1986 21:52:09 +0000 (21:52 +0000)
committerceriel <none@none>
Mon, 24 Nov 1986 21:52:09 +0000 (21:52 +0000)
mach/m68k2/top/table [new file with mode: 0644]

diff --git a/mach/m68k2/top/table b/mach/m68k2/top/table
new file mode 100644 (file)
index 0000000..8ea7726
--- /dev/null
@@ -0,0 +1,178 @@
+
+/* 68000 desciptor table for ACK target optimizer */
+
+MAXOP 2;
+
+%%;
+
+/* useful addressing modes-> */
+
+CONST          {VAL[0] == '#'                  };      /* constant */
+NUM            {is_number(VAL)                 };
+A,B            {no_side_effects(VAL)           };
+D              {VAL[0] != '#' && !is_areg(VAL) };      /* not an addr. reg */
+X,Y            {TRUE                           };
+DREG,DREG2     {is_dreg(VAL)                   };       /* data register */
+DSREG          {is_dsreg(VAL)                  };      /* data register */
+AREG           {is_areg(VAL)                   };      /* addressregister */
+LAB,L1,L2      {VAL[0] == 'I'                  };      /* label */
+BITNO          {TRUE                           };
+
+%%;
+
+/* optimization patterns-> */
+
+/* rewriting rules */
+tst X                                  ->      tst.w X ;
+cmp X,Y                                        ->      cmp.w X,Y ;
+
+/* special instructions */
+move.w #0,D                            ->      clr.w D ;
+move.l #0,D                            ->      clr.l D ;
+move.l #0,AREG                         ->      sub.l AREG,AREG ;
+
+/* tst-elimination */
+add.l #2,sp : tst.w X {no_part("sp",X)}        ->      move.w X,(sp)+ ;
+add.l #4,sp : tst.l D {no_part("sp",D)}        ->      move.l D,(sp)+ ;
+add.l #2,sp : move.w X,-(sp)           ->      move.w X,(sp) ;
+add.l #4,sp : move.l X,-(sp)           ->      move.l X,(sp) ;
+move.w A,X : tst.w A                   ->      move.w A,X ;
+move.w X,A : tst.w A                   ->      move.w X,A ;
+move.l A,D : tst.l A {no_part(D,A)}    ->      move.l A,D ;
+move.l X,D : tst.l D                   ->      move.l X,D ;
+move.l A,AREG : tst.l A
+               {no_part(AREG,A)}       ->      tst.l A: move.l A,AREG ;
+move.l X,AREG : move.l AREG,DREG :
+       tst.l DREG : beq LAB            ->      move.l X,DREG :
+                                               move.l DREG,AREG: beq LAB ;
+move.l X,AREG : move.l AREG,DREG :
+       tst.l DREG : bne LAB            ->      move.l X,DREG :
+                                               move.l DREG,AREG: bne LAB ;
+
+/* redundant move */
+move.w DREG,DREG2 : move.w DREG2,DREG  ->      move.w DREG,DREG2 ;
+
+/* register subsumption */
+move.w DREG,A : ANY A,X
+       {reg_subs_allowed(ANY) &&
+        !is_dreg(A)    }               ->      move.w DREG,A : ANY DREG,X ;
+
+/* change "cmp" into "add" or "sub" (possibly "addq" or "subq") */
+cmp.w #-NUM,DSREG : beq LAB            ->      add.w #NUM,DSREG : beq LAB ;
+cmp.l #-NUM,DSREG : beq LAB            ->      add.l #NUM,DSREG : beq LAB ;
+cmp.w #-NUM,DSREG : bne LAB            ->      add.w #NUM,DSREG : bne LAB ;
+cmp.l #-NUM,DSREG : bne LAB            ->      add.l #NUM,DSREG : bne LAB ;
+
+cmp.w #NUM,DSREG : beq LAB             ->      sub.w #NUM,DSREG : beq LAB ;
+cmp.l #NUM,DSREG : beq LAB             ->      sub.l #NUM,DSREG : beq LAB ;
+cmp.w #NUM,DSREG : bne LAB             ->      sub.w #NUM,DSREG : bne LAB ;
+cmp.l #NUM,DSREG : bne LAB             ->      sub.l #NUM,DSREG : bne LAB ;
+
+/* addq and subq */
+lea -1(AREG),AREG                      ->      sub.l #1,AREG ;
+add.w #-NUM,X                          ->      sub.w #NUM,X ;
+add.l #-NUM,X                          ->      sub.l #NUM,X ;
+sub.w #-NUM,X                          ->      add.w #NUM,X ;
+sub.l #-NUM,X                          ->      add.l #NUM,X ;
+
+/* bit-test instruction */
+move.b X,DSREG : and.w #NUM,DSREG : 
+ tst.w DSREG : beq LAB 
+ { bitno(NUM,BITNO)}                   ->      btst #BITNO,X ;
+
+/* skip over jump */
+beq L1 : bra L2: labdef L1             ->      bne L2 : labdef L1 ;
+bge L1 : bra L2: labdef L1             ->      blt L2 : labdef L1 ;
+bgt L1 : bra L2: labdef L1             ->      ble L2 : labdef L1 ;
+blt L1 : bra L2: labdef L1             ->      bge L2 : labdef L1 ;
+ble L1 : bra L2: labdef L1             ->      bgt L2 : labdef L1 ;
+bne L1 : bra L2: labdef L1             ->      beq L2 : labdef L1 ;
+
+%%;
+
+/* auxiliary routines: */
+
+int no_side_effects(s)
+       register char *s;
+{
+
+       for(;;) {
+               switch(*s++) {
+                       case '\0': return TRUE;
+                       case '-':  if (*s == '(') return FALSE; break;
+                       case ')':  if (*s == '+') return FALSE; break;
+               }
+       }
+       /* NOTREACHED */
+}
+
+
+int is_dreg(s)
+       register char *s;
+{
+       return *s++ == 'd' && *s >= '0' && *s++ <= '7' && *s == '\0';
+}
+
+int is_dsreg(s)
+       register char *s;
+{
+       return *s++ == 'd' && *s >= '0' && *s++ <= '2' && *s == '\0';
+}
+
+int is_areg(s)
+       register char *s;
+{
+       return *s++ == 'a' && *s >= '0' && *s++ <= '6' && *s == '\0';
+}
+
+int no_part(part,s)
+       char *part,*s;
+{
+       char *tmp1,*tmp2;
+
+       while (*s != '\0') {
+               if (*s == *part) {
+                       for (tmp1=part,tmp2=s;;  tmp1++,tmp2++) {
+                               if (*tmp1== '\0') return FALSE;
+                               if (*tmp1 != *tmp2) break;
+                       }
+               }
+               s++;
+       }
+       return TRUE;
+}
+
+
+/* see if register subsumption is allowed for instruction Opc */
+
+int reg_subs_allowed(opc)
+       char *opc;
+{
+       return strcmp(opc,"cmp") != 0 && strcmp(opc,"lea") != 0;
+}
+
+int is_number(s)
+       register char *s;
+{
+       while (*s != '\0') {
+               if (*s < '0' || *s++ > '9') return FALSE;
+       }
+       return TRUE;
+}
+
+int bitno(s,no)
+       char *s,*no;
+{
+       int n,i;
+
+       n = atoi(s);
+       if (n < 1 || n > 128) return FALSE;
+       for (i = 0; i < 8 ; i++) {
+               if (n == 1) {
+                       sprintf(no,"%d",i);
+                       return TRUE;
+               }
+               n >>= 1;
+       }
+       return FALSE;
+}