table 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /* 68000 desciptor table for ACK target optimizer */
  2. MAXOP 2;
  3. PAREN_OPEN "(";
  4. PAREN_CLOSE ")";
  5. %%;
  6. /* useful addressing modes-> */
  7. CONST {VAL[0] == '#' }; /* constant */
  8. NUM {is_number(VAL) };
  9. A,B {no_side_effects(VAL) };
  10. D {VAL[0] != '#' && !is_areg(VAL) }; /* not an addr. reg */
  11. X,Y {TRUE };
  12. DREG,DREG2 {is_dreg(VAL) }; /* data register */
  13. DSREG {is_dsreg(VAL) }; /* data register */
  14. AREG {is_areg(VAL) }; /* addressregister */
  15. LAB,L1,L2 {VAL[0] == 'I' }; /* label */
  16. BITNO {TRUE };
  17. %%;
  18. /* optimization patterns-> */
  19. /* rewriting rules */
  20. tst X -> tst.w X ;
  21. cmp X,Y -> cmp.w X,Y ;
  22. /* special instructions */
  23. move.w #0,D -> clr.w D ;
  24. move.l #0,D -> clr.l D ;
  25. move.l #0,AREG -> sub.l AREG,AREG ;
  26. /* tst-elimination */
  27. add.l #2,sp : tst.w X {no_part("sp",X)} -> move.w X,(sp)+ ;
  28. add.l #4,sp : tst.l D {no_part("sp",D)} -> move.l D,(sp)+ ;
  29. add.l #2,sp : move.w X,-(sp) -> move.w X,(sp) ;
  30. add.l #4,sp : move.l X,-(sp) -> move.l X,(sp) ;
  31. add.l #4,sp : pea (NUM) -> move.l #NUM,(sp) ;
  32. add.l #NUM,sp : unlk AREG -> unlk AREG ;
  33. move.w A,X : tst.w A -> move.w A,X ;
  34. move.w X,A : tst.w A -> move.w X,A ;
  35. move.l A,D : tst.l A {no_part(D,A)} -> move.l A,D ;
  36. move.l X,D : tst.l D -> move.l X,D ;
  37. move.l A,AREG : tst.l A
  38. {no_part(AREG,A)} -> tst.l A: move.l A,AREG ;
  39. move.l X,AREG : move.l AREG,DREG :
  40. tst.l DREG : beq LAB -> move.l X,DREG :
  41. move.l DREG,AREG: beq LAB ;
  42. move.l X,AREG : move.l AREG,DREG :
  43. tst.l DREG : bne LAB -> move.l X,DREG :
  44. move.l DREG,AREG: bne LAB ;
  45. /* redundant move */
  46. move.l DREG,DREG2 : move.l DREG2,DREG -> move.l DREG,DREG2 ;
  47. move.w DREG,DREG2 : move.w DREG2,DREG -> move.w DREG,DREG2 ;
  48. /* register subsumption */
  49. move.w DREG,A : ANY A,X
  50. {reg_subs_allowed(ANY) &&
  51. !is_dreg(A) } -> move.w DREG,A : ANY DREG,X ;
  52. move.l DREG,A : ANY A,X
  53. {reg_subs_allowed(ANY) &&
  54. !is_dreg(A) } -> move.l DREG,A : ANY DREG,X ;
  55. cmp.b A,A : beq LAB -> bra LAB ;
  56. cmp.w A,A : beq LAB -> bra LAB ;
  57. cmp.l A,A : beq LAB -> bra LAB ;
  58. /* cannot delete cmp's because they affect condition codes (obvious, but ... )*/
  59. cmp.b A,A : bne LAB -> cmp.b A,A ;
  60. cmp.w A,A : bne LAB -> cmp.w A,A ;
  61. cmp.l A,A : bne LAB -> cmp.l A,A ;
  62. /* change some compares to tests */
  63. cmp.w #0,X : beq LAB -> tst.w X : beq LAB ;
  64. cmp.w #0,X : bne LAB -> tst.w X : bne LAB ;
  65. cmp.w #0,X : blt LAB -> tst.w X : blt LAB ;
  66. cmp.w #0,X : ble LAB -> tst.w X : ble LAB ;
  67. cmp.w #0,X : bge LAB -> tst.w X : bge LAB ;
  68. cmp.w #0,X : bgt LAB -> tst.w X : bgt LAB ;
  69. cmp.l #0,X : beq LAB -> tst.l X : beq LAB ;
  70. cmp.l #0,X : bne LAB -> tst.l X : bne LAB ;
  71. cmp.l #0,X : blt LAB -> tst.l X : blt LAB ;
  72. cmp.l #0,X : ble LAB -> tst.l X : ble LAB ;
  73. cmp.l #0,X : bge LAB -> tst.l X : bge LAB ;
  74. cmp.l #0,X : bgt LAB -> tst.l X : bgt LAB ;
  75. cmp.w X,#0 : beq LAB -> tst.w X : beq LAB ;
  76. cmp.w X,#0 : bne LAB -> tst.w X : bne LAB ;
  77. cmp.w X,#0 : blt LAB -> tst.w X : bgt LAB ;
  78. cmp.w X,#0 : ble LAB -> tst.w X : bge LAB ;
  79. cmp.w X,#0 : bge LAB -> tst.w X : ble LAB ;
  80. cmp.w X,#0 : bgt LAB -> tst.w X : blt LAB ;
  81. cmp.l X,#0 : beq LAB -> tst.l X : beq LAB ;
  82. cmp.l X,#0 : bne LAB -> tst.l X : bne LAB ;
  83. cmp.l X,#0 : blt LAB -> tst.l X : bgt LAB ;
  84. cmp.l X,#0 : ble LAB -> tst.l X : bge LAB ;
  85. cmp.l X,#0 : bge LAB -> tst.l X : ble LAB ;
  86. cmp.l X,#0 : bgt LAB -> tst.l X : blt LAB ;
  87. /* change "cmp" into "add" or "sub" (possibly "addq" or "subq") */
  88. cmp.w #-NUM,DSREG : beq LAB -> add.w #NUM,DSREG : beq LAB ;
  89. cmp.l #-NUM,DSREG : beq LAB -> add.l #NUM,DSREG : beq LAB ;
  90. cmp.w #-NUM,DSREG : bne LAB -> add.w #NUM,DSREG : bne LAB ;
  91. cmp.l #-NUM,DSREG : bne LAB -> add.l #NUM,DSREG : bne LAB ;
  92. cmp.w #NUM,DSREG : beq LAB -> sub.w #NUM,DSREG : beq LAB ;
  93. cmp.l #NUM,DSREG : beq LAB -> sub.l #NUM,DSREG : beq LAB ;
  94. cmp.w #NUM,DSREG : bne LAB -> sub.w #NUM,DSREG : bne LAB ;
  95. cmp.l #NUM,DSREG : bne LAB -> sub.l #NUM,DSREG : bne LAB ;
  96. /* addq and subq */
  97. lea -1(AREG),AREG -> sub.l #1,AREG ;
  98. add.w #-NUM,X -> sub.w #NUM,X ;
  99. add.l #-NUM,X -> sub.l #NUM,X ;
  100. sub.w #-NUM,X -> add.w #NUM,X ;
  101. sub.l #-NUM,X -> add.l #NUM,X ;
  102. /* bit-test instruction */
  103. move.b X,DSREG : and.w #NUM,DSREG :
  104. tst.w DSREG : beq LAB
  105. { bitno(NUM,BITNO)} -> btst #BITNO,X ;
  106. move.b X,DSREG : and.l #NUM,DSREG :
  107. tst.l DSREG : beq LAB
  108. { bitno(NUM,BITNO)} -> btst #BITNO,X ;
  109. /* skip over jump */
  110. beq L1 : bra L2: labdef L1 -> bne L2 : labdef L1 ;
  111. bge L1 : bra L2: labdef L1 -> blt L2 : labdef L1 ;
  112. bgt L1 : bra L2: labdef L1 -> ble L2 : labdef L1 ;
  113. blt L1 : bra L2: labdef L1 -> bge L2 : labdef L1 ;
  114. ble L1 : bra L2: labdef L1 -> bgt L2 : labdef L1 ;
  115. bne L1 : bra L2: labdef L1 -> beq L2 : labdef L1 ;
  116. %%;
  117. /* auxiliary routines: */
  118. int no_side_effects(s)
  119. register char *s;
  120. {
  121. for(;;) {
  122. switch(*s++) {
  123. case '\0': return TRUE;
  124. case '-': if (*s == '(') return FALSE; break;
  125. case ')': if (*s == '+') return FALSE; break;
  126. }
  127. }
  128. /* NOTREACHED */
  129. }
  130. int is_dreg(s)
  131. register char *s;
  132. {
  133. return *s++ == 'd' && *s >= '0' && *s++ <= '7' && *s == '\0';
  134. }
  135. int is_dsreg(s)
  136. register char *s;
  137. {
  138. return *s++ == 'd' && *s >= '0' && *s++ <= '2' && *s == '\0';
  139. }
  140. int is_areg(s)
  141. register char *s;
  142. {
  143. return *s++ == 'a' && *s >= '0' && *s++ <= '6' && *s == '\0';
  144. }
  145. int no_part(part,s)
  146. char *part,*s;
  147. {
  148. char *tmp1,*tmp2;
  149. while (*s != '\0') {
  150. if (*s == *part) {
  151. for (tmp1=part,tmp2=s;; tmp1++,tmp2++) {
  152. if (*tmp1== '\0') return FALSE;
  153. if (*tmp1 != *tmp2) break;
  154. }
  155. }
  156. s++;
  157. }
  158. return TRUE;
  159. }
  160. /* see if register subsumption is allowed for instruction Opc */
  161. int reg_subs_allowed(opc)
  162. char *opc;
  163. {
  164. return strcmp(opc,"cmp") != 0 && strcmp(opc,"lea") != 0;
  165. }
  166. int is_number(s)
  167. register char *s;
  168. {
  169. while (*s != '\0') {
  170. if (*s < '0' || *s++ > '9') return FALSE;
  171. }
  172. return TRUE;
  173. }
  174. int bitno(s,no)
  175. char *s,*no;
  176. {
  177. int n,i;
  178. n = atoi(s);
  179. if (n < 1 || n > 128) return FALSE;
  180. for (i = 0; i < 8 ; i++) {
  181. if (n == 1) {
  182. sprintf(no,"%d",i);
  183. return TRUE;
  184. }
  185. n >>= 1;
  186. }
  187. return FALSE;
  188. }