table 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. /* VAX descriptor table for ACK target optimizer,
  2. */
  3. /* tunable constants-> */
  4. MAXOP 4;
  5. MAXLINELEN 50;
  6. LABEL_STARTER 'I';
  7. OPC_TERMINATOR ' ';
  8. %%;
  9. ZERO {strcmp(VAL,"$0") == 0};
  10. ONE {strcmp(VAL,"$1") == 0};
  11. M_ONE {strcmp(VAL,"$-1") == 0};
  12. CONST {VAL[0] == '$'};
  13. NUM,NUM1 {is_number(VAL)};
  14. REG {is_register(VAL)};
  15. SREG {is_scratchreg(VAL)};
  16. LAB,LAB2 {VAL[0] == LABEL_STARTER};
  17. A,B {no_side_effects(VAL) };
  18. NO_INDEX {strchr(VAL, '[') == 0};
  19. X,Y,LOG {TRUE};
  20. %%;
  21. movab 1(X),X -> incl X;
  22. movab -1(X),X -> decl X;
  23. movzbw ZERO,X -> clrw X;
  24. movzbl ZERO,X -> clrl X;
  25. movb ZERO,X -> clrb X;
  26. movw ZERO,X -> clrw X;
  27. movl ZERO,X -> clrl X;
  28. cvtbw ZERO,X -> clrw X;
  29. cvtww ZERO,X -> clrw X;
  30. cvtbl ZERO,X -> clrl X;
  31. cvtwl ZERO,X -> clrl X;
  32. /* change 3-operand instructions to 2-operand instructions */
  33. addw3 X,A,A -> addw2 X,A;
  34. addl3 X,A,A -> addl2 X,A;
  35. addf3 X,A,A -> addf2 X,A;
  36. addd3 X,A,A -> addd2 X,A;
  37. addw3 A,Y,A -> addw2 Y,A;
  38. addl3 A,Y,A -> addl2 Y,A;
  39. addf3 A,Y,A -> addf2 Y,A;
  40. addd3 A,Y,A -> addd2 Y,A;
  41. subw3 X,A,A -> subw2 X,A;
  42. subl3 X,A,A -> subl2 X,A;
  43. subf3 X,A,A -> subf2 X,A;
  44. subd3 X,A,A -> subd2 X,A;
  45. mulw3 X,A,A -> mulw2 X,A;
  46. mull3 X,A,A -> mull2 X,A;
  47. mulf3 X,A,A -> mulf2 X,A;
  48. muld3 X,A,A -> muld2 X,A;
  49. mulw3 A,Y,A -> mulw2 Y,A;
  50. mull3 A,Y,A -> mull2 Y,A;
  51. mulf3 A,Y,A -> mulf2 Y,A;
  52. muld3 A,Y,A -> muld2 Y,A;
  53. divw3 X,A,A -> divw2 X,A;
  54. divl3 X,A,A -> divl2 X,A;
  55. divf3 X,A,A -> divf2 X,A;
  56. divd3 X,A,A -> divd2 X,A;
  57. xorw3 X,A,A -> xorw2 X,A;
  58. xorl3 X,A,A -> xorl2 X,A;
  59. bisw3 X,A,A -> bisw2 X,A;
  60. bisl3 X,A,A -> bisl2 X,A;
  61. bisw3 A,Y,A -> bisw2 Y,A;
  62. bisl3 A,Y,A -> bisl2 Y,A;
  63. bicw3 X,A,A -> bicw2 X,A;
  64. bicl3 X,A,A -> bicl2 X,A;
  65. /* eliminate negative constants */
  66. addw2 $-NUM,X -> subw2 $NUM,X;
  67. addl2 $-NUM,X -> subl2 $NUM,X;
  68. addw3 $-NUM,X,Y -> subw3 $NUM,X,Y;
  69. addl3 $-NUM,X,Y -> subl3 $NUM,X,Y;
  70. addw3 X,$-NUM,Y -> subw3 $NUM,X,Y;
  71. addl3 X,$-NUM,Y -> subl3 $NUM,X,Y;
  72. subw2 $-NUM,X -> addw2 $NUM,X;
  73. subl2 $-NUM,X -> addl2 $NUM,X;
  74. subw3 $-NUM,X,Y -> addw3 $NUM,X,Y;
  75. subl3 $-NUM,X,Y -> addl3 $NUM,X,Y;
  76. /* use special instructions */
  77. addw2 ONE,X -> incw X;
  78. addl2 ONE,X -> incl X;
  79. subw2 ONE,X -> decw X;
  80. subl2 ONE,X -> decl X;
  81. addw2 M_ONE,X -> decw X;
  82. addl2 M_ONE,X -> decl X;
  83. subw2 M_ONE,X -> incw X;
  84. subl2 M_ONE,X -> incl X;
  85. /* careful! jbs has byte argument, jlbs has long argument, so be very careful
  86. with indexed mode
  87. */
  88. bitw $NUM,NO_INDEX : jneq LAB
  89. {is_poweroftwo(NUM,LOG)}-> jbs $LOG,NO_INDEX,LAB;
  90. bitl $NUM,NO_INDEX : jneq LAB
  91. {is_poweroftwo(NUM,LOG)}-> jbs $LOG,NO_INDEX,LAB;
  92. bitw $NUM,NO_INDEX : jeql LAB
  93. {is_poweroftwo(NUM,LOG)}-> jbc $LOG,NO_INDEX,LAB;
  94. bitl $NUM,NO_INDEX : jeql LAB
  95. {is_poweroftwo(NUM,LOG)}-> jbc $LOG,NO_INDEX,LAB;
  96. bitw ONE,NO_INDEX : jneq LAB -> jlbs NO_INDEX,LAB;
  97. bitl ONE,A : jneq LAB -> jlbs A,LAB;
  98. bitw ONE,NO_INDEX : jneq LAB -> jlbc NO_INDEX,LAB;
  99. bitl ONE,A : jneq LAB -> jlbc A,LAB;
  100. ashl $-NUM,A,REG : bicw2 $~NUM1,REG
  101. {is_p2m1(NUM1,LOG)} -> extzv $NUM,$LOG,A,REG;
  102. ashl $-NUM,A,REG : bicl2 $~NUM1,REG
  103. {is_p2m1(NUM1,LOG)} -> extzv $NUM,$LOG,A,REG;
  104. /* stack optimizations */
  105. movl (sp)+,X : pushl X -> movl (sp),X;
  106. tstw (sp)+ : movw X,-(sp) -> movw X,(sp);
  107. tstl (sp)+ : movl X,-(sp) -> movl X,(sp);
  108. tstw (sp)+ : clrw -(sp) -> clrw (sp);
  109. tstl (sp)+ : clrl -(sp) -> clrl (sp);
  110. tstw (sp)+ : movzbw X,-(sp) -> movzbw X,(sp);
  111. tstl (sp)+ : movzbl X,-(sp) -> movzbl X,(sp);
  112. tstw (sp)+ : cvtbw X,-(sp) -> cvtbw X,(sp);
  113. tstl (sp)+ : cvtbl X,-(sp) -> cvtbl X,(sp);
  114. tstw (sp)+ : tstw X -> movw X,(sp)+;
  115. tstl (sp)+ : tstl X -> movl X,(sp)+;
  116. tstl (sp)+ : pushl X -> movl X,(sp);
  117. tstl (sp)+ : pushab X -> movab X,(sp);
  118. tstl (sp)+ : pushaw X -> movaw X,(sp);
  119. tstl (sp)+ : pushal X -> moval X,(sp);
  120. tstl (sp)+ : pushaq X -> movaq X,(sp);
  121. /* push constants */
  122. clrw -(sp) : movw $NUM,-(sp) -> pushl $NUM;
  123. clrw -(sp) : mnegw $NUM, -(sp) -> movzwl $-NUM,-(sp);
  124. clrw -(sp) : movw X,-(sp) -> movzwl X,-(sp);
  125. clrw -(sp) : cvtbw $NUM,-(sp) -> pushl $NUM;
  126. clrw -(sp) : cvtbw CONST,-(sp) -> movzwl CONST,-(sp);
  127. /* compare with zero */
  128. cmpb X,ZERO -> tstb X;
  129. cmpw X,ZERO -> tstw X;
  130. cmpl X,ZERO -> tstl X;
  131. cmpb ZERO,X : jneq LAB -> tstb X: jneq LAB;
  132. cmpw ZERO,X : jneq LAB -> tstw X: jneq LAB;
  133. cmpl ZERO,X : jneq LAB -> tstl X: jneq LAB;
  134. cmpb ZERO,X : jeql LAB -> tstb X: jeql LAB;
  135. cmpw ZERO,X : jeql LAB -> tstw X: jeql LAB;
  136. cmpl ZERO,X : jeql LAB -> tstl X: jeql LAB;
  137. cmpb ZERO,X : jgtr LAB -> tstb X: jlss LAB;
  138. cmpw ZERO,X : jgtr LAB -> tstw X: jlss LAB;
  139. cmpl ZERO,X : jgtr LAB -> tstl X: jlss LAB;
  140. cmpb ZERO,X : jlss LAB -> tstb X: jgtr LAB;
  141. cmpw ZERO,X : jlss LAB -> tstw X: jgtr LAB;
  142. cmpl ZERO,X : jlss LAB -> tstl X: jgtr LAB;
  143. cmpb ZERO,X : jgeq LAB -> tstb X: jleq LAB;
  144. cmpw ZERO,X : jgeq LAB -> tstw X: jleq LAB;
  145. cmpl ZERO,X : jgeq LAB -> tstl X: jleq LAB;
  146. cmpb ZERO,X : jleq LAB -> tstb X: jgeq LAB;
  147. cmpw ZERO,X : jleq LAB -> tstw X: jgeq LAB;
  148. cmpl ZERO,X : jleq LAB -> tstl X: jgeq LAB;
  149. /* compare with -1 */
  150. cmpw M_ONE,SREG : jeql LAB -> incw SREG : jeql LAB;
  151. cmpl M_ONE,SREG : jeql LAB -> incl SREG : jeql LAB;
  152. cmpw M_ONE,SREG : jneq LAB -> incw SREG : jneq LAB;
  153. cmpl M_ONE,SREG : jneq LAB -> incl SREG : jneq LAB;
  154. /* eliminate redundant tests */
  155. movw X,A : tstw A -> movw X,A;
  156. movl X,A : tstl A -> movl X,A;
  157. movw A,X : tstw A -> movw A,X;
  158. movl A,X : tstl A -> movl A,X;
  159. /* skip over jumps */
  160. jeql LAB : jbr LAB2 : labdef LAB -> jneq LAB2 : labdef LAB;
  161. jgeq LAB : jbr LAB2 : labdef LAB -> jlss LAB2 : labdef LAB;
  162. jgtr LAB : jbr LAB2 : labdef LAB -> jleq LAB2 : labdef LAB;
  163. jlss LAB : jbr LAB2 : labdef LAB -> jgeq LAB2 : labdef LAB;
  164. jleq LAB : jbr LAB2 : labdef LAB -> jgtr LAB2 : labdef LAB;
  165. jneq LAB : jbr LAB2 : labdef LAB -> jeql LAB2 : labdef LAB;
  166. /* Register propagation */
  167. movl REG,A : ANY *A -> movl REG,A : ANY (REG);
  168. movl REG,A : ANY *A,X -> movl REG,A : ANY (REG),X;
  169. movl REG,A : ANY X,*A -> movl REG,A : ANY X,(REG);
  170. movl REG,A : ANY *A,X,Y -> movl REG,A : ANY (REG),X,Y;
  171. movl REG,A : ANY X,*A,Y -> movl REG,A : ANY X,(REG),Y;
  172. movl REG,A : ANY X,Y,*A -> movl REG,A : ANY X,Y,(REG);
  173. /* convert floats, doubles */
  174. cvtlf X,A : cvtfd A,A -> cvtld X,A;
  175. cvtdf A,B : cvtfd B,A -> cvtdf A,B;
  176. %%;
  177. /* Auxiliary routines: */
  178. int is_number(s)
  179. register char *s;
  180. {
  181. while (*s >= '0' && *s <= '9') s++;
  182. return *s == '\0';
  183. }
  184. int is_poweroftwo(s,t)
  185. char *s,*t;
  186. {
  187. long arg, pow;
  188. register int i;
  189. arg = atol(s);
  190. pow = 1;
  191. i = 0;
  192. while (pow > 0) {
  193. if (pow == arg) {
  194. sprintf(t,"%d",i);
  195. return 1;
  196. }
  197. pow <<= 1;
  198. i++;
  199. }
  200. return 0;
  201. }
  202. int is_p2m1(s,t)
  203. char *s,*t;
  204. {
  205. long arg;
  206. char buf[MAXLINELEN];
  207. arg = atol(s)+1;
  208. sprintf(buf,"%ld",arg);
  209. return is_poweroftwo(buf,t);
  210. }
  211. int no_side_effects(s)
  212. register char *s;
  213. {
  214. for(;;) {
  215. switch(*s++) {
  216. case '\0': return TRUE;
  217. case '-': if (*s == '(') return FALSE; break;
  218. case ')': if (*s == '+') return FALSE; break;
  219. }
  220. }
  221. /* NOTREACHED */
  222. }
  223. int is_register(s)
  224. register char *s;
  225. {
  226. if (*s++ == 'r' && *s >= '0' && *s <= '9') {
  227. if (*s++ == '1' && (*s == '0' || *s == '1')) s++;
  228. return *s == '\0';
  229. }
  230. return FALSE;
  231. }
  232. int is_scratchreg(s)
  233. register char *s;
  234. {
  235. return *s++ == 'r' && *s >= '0' && *s++ <= '3' && *s == '\0';
  236. }