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