From: ceriel Date: Mon, 24 Nov 1986 21:52:09 +0000 (+0000) Subject: Initial revision X-Git-Tag: release-5-5~5139 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=552f5a3f617db3393789f36bf83f2ba2977edaa1;p=ack.git Initial revision --- diff --git a/mach/m68k2/top/table b/mach/m68k2/top/table new file mode 100644 index 000000000..8ea7726dc --- /dev/null +++ b/mach/m68k2/top/table @@ -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; +}