Pristine Ack-5.5
[Ack-5.5.git] / mach / m68k2 / as / mach4.c
1 /* $Id: mach4.c,v 2.10 1994/06/24 13:02:53 ceriel Exp $ */
2 /*
3  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4  * See the copyright notice in the ACK home directory, in the file "Copyright".
5  */
6 /* @(#)mach4.c  1.11 */
7 /*
8  *  Motorola 68000/68010 syntax rules
9  */
10
11 operation
12         :       { curr_instr = curr_token; }
13                 _operation
14         ;
15
16 _operation
17         :       bcdx DREG ',' DREG
18                         {       emit2($1 | $2 | $4<<9);}
19         |       bcdx '-' '(' AREG ')' ',' '-' '(' AREG ')'
20                         {       emit2($1 | $4 | $9<<9 | 010);}
21         |       ADD sizedef ea_ea
22                         {       add($1, $2);}
23         |       AND sizenon ea_ea
24                         {       and($1, $2);}
25         |       SHIFT sizedef ea_ea
26                         {       shift_op($1, $2);}
27         |       BR expr
28                         {       branch($1, $2);}
29         |       DBR DREG ',' expr
30                         {       $4.val -= (DOTVAL+2);
31                                 Xfit(fitw($4.val));
32                                 emit2($1 | $2);
33 #ifdef RELOCATION
34                                 newrelo($4.typ, RELPC|RELO2|RELBR|RELWR);
35 #endif
36                                 emit2(loww($4.val));
37                         }
38         |       BITOP ea_ea
39                         {       bitop($1);}
40         |       OP_EA_D sizedef ea ',' DREG
41                         {       if ($2 != SIZE_W) {
42                                         serror("illegal size");
43                                 }
44                                 emit2($1 | mrg_2 | $5<<9);
45                                 ea_2(SIZE_W, DTA);
46                         }
47         |       LEA ea ',' AREG
48                         {       emit2(040700 | mrg_2 | $4<<9);
49                                 ea_2(SIZE_L, CTR);
50                         }
51         |       op_ea ea
52                         {       emit2(($1&0177700) | mrg_2);
53                                 ea_2($1&0300, $1&017);
54                         }
55         |       OP_NOOP
56                         {       emit2($1);}
57         |       CMP sizedef ea_ea
58                         {       cmp($2);}
59         |       MOVE sizenon ea_ea
60                         {       move($2);}
61         |       MOVEP sizedef ea_ea
62                         {       movep($2);}
63         |       MOVEM sizedef regs ',' notimmreg
64                         {       movem(0, $2, $3);}
65         |       MOVEM sizedef notimmreg ',' regs
66                         {       movem(1, $2, $5);}
67         |       MOVES sizedef ea_ea
68                         {       test68010();
69                                 if (mrg_1 <= 017) {
70                                         emit2(007000 | $2 | mrg_2);
71                                         emit2(mrg_1 << 12 | 04000);
72                                         ea_2($2,ALT|MEM);
73                                 } else if (mrg_2 <= 017) {
74                                         emit2(007000 | $2 | mrg_1);
75                                         emit2(mrg_2 << 12);
76                                         ea_1($2,ALT|MEM);
77                                 } else
78                                         badoperand();
79                         }
80         |       MOVEC creg ',' reg
81                         {       test68010();
82                                 emit2(047172); emit2($2 | $4<<12);
83                         }
84         |       MOVEC reg ',' creg
85                         {       test68010();
86                                 emit2(047173); emit2($4 | $2<<12);
87                         }
88         |       EXG reg ',' reg
89                         {       if (($2 & 010) == 0)
90                                         emit2(
91                                                 (0140500|$4|$2<<9)
92                                                 +
93                                                 (($4&010)<<3)
94                                         );
95                                 else
96                                         emit2(
97                                                 (0140610|$2|($4&07)<<9)
98                                                 -
99                                                 (($4&010)<<3)
100                                         );
101                         }
102         |       OP_EXT sizedef DREG
103                         {       checksize($2, 2|4); emit2(044000 | $2+0100 | $3);}
104         |       SWAP DREG
105                         {       emit2(044100 | $2);}
106         |       STOP imm
107                         {       emit2($1); ea_2(SIZE_W, 0);}
108         |       LINK AREG ',' imm
109                         {       emit2(047120 | $2); ea_2(SIZE_W, 0);}
110         |       UNLK AREG
111                         {       emit2(047130 | $2);}
112         |       TRAP '#' absexp
113                         {       Xfit(fit4($3)); emit2(047100|low4($3));}
114         |       RTD imm
115                         {       test68010();
116                                 emit2(047164);
117                                 ea_2(SIZE_W, 0);
118                         }
119         |       MODEL
120                         {       model = $1;}
121         |       fp_op
122         ;
123 bcdx    :       ABCD
124         |       ADDX sizedef
125                         {       $$ = $1 | $2;}
126         ;
127 creg    :       CREG
128         |       SPEC    {       if ($1 != 075) badoperand(); $$ = 04000;}
129         ;
130 op_ea   :       OP_EA
131         |       SZ_EA sizedef
132                         {       $$ = $1 | $2;}
133         ;
134 regs    :       rrange
135         |       regs '/' rrange
136                         {       $$ = $1 | $3;}
137         ;
138 rrange  :       reg
139                         {       $$ = 1<<$1;}
140         |       reg '-' reg
141                         {       if ($1 > $3)
142                                         badoperand();
143                                 for ($$ = 0; $1 <= $3; $1++)
144                                         $$ |= (1<<$1);
145                         }
146         ;
147 ea      :       DREG
148                         {       mrg_2 = $1;}
149         |       AREG
150                         {       mrg_2 = 010 | $1;}
151         |       SPEC
152                         {       mrg_2 = $1;}
153         |       notimmreg
154         |       imm
155         ;
156 notimmreg
157         :       '(' AREG ')'
158                         {       mrg_2 = 020 | $2;}
159         |       '(' AREG ')' '+'
160                         {       mrg_2 = 030 | $2;}
161         |       '-' '(' AREG ')'
162                         {       mrg_2 = 040 | $3;}
163         |       expr sizenon
164                         {       exp_2 = $1; ea707172($2);
165                                 RELOMOVE(rel_2, relonami);
166                         }
167         |       expr '(' reg sizenon ')'
168                         {       exp_2 = $1; ea5x73($3, $4);
169                                 RELOMOVE(rel_2, relonami);
170                         }
171         |       expr '(' AREG ',' reg sizedef ')'
172                         {       exp_2 = $1; ea6x($3, $5, $6);
173                                 RELOMOVE(rel_2, relonami);
174                         }
175         |       expr '(' PC ')'
176                         {       exp_2 = $1; ea72();
177                                 RELOMOVE(rel_2, relonami);
178                         }
179         |       expr '(' PC ',' reg sizedef ')'
180                         {       exp_2 = $1; ea73($5, $6);
181                                 RELOMOVE(rel_2, relonami);
182                         }
183         ;
184 imm     :       '#' expr
185                         {       mrg_2 = 074; exp_2 = $2;
186                                 RELOMOVE(rel_2, relonami);
187                         }
188         ;
189 reg     :       DREG
190         |       AREG
191                         {       $$ = $1 | 010;}
192         ;
193 sizedef :       /* empty */
194                         {       $$ = SIZE_DEF;}
195         |       SIZE
196         ;
197 sizenon :       /* empty */
198                         {       $$ = SIZE_NON;}
199         |       SIZE
200         ;
201 ea_ea   :       ea ','
202                         {       mrg_1 = mrg_2; exp_1 = exp_2;
203                                 RELOMOVE(rel_1, rel_2);
204                         }
205                 ea
206         ;
207 fp_op   :       CP
208                         {       co_id = $1; }
209                 fp_op1
210         |               {       co_id = DEF_FP; }
211                 fp_op1
212         ;
213 fp_op1  :       FMOVE fsize ea ',' FPCR
214                         {       check_fsize($2, FSIZE_L);
215                                 if ((mrg_2&070) == 010 && $5 != 001)
216                                         badoperand();
217                                 emit2((0170000|co_id|mrg_2));
218                                 emit2((0100000|($5<<10)));
219                                 ea_2(SIZE_L, 0);
220                         }
221         |       FMOVE fsize FPCR ',' ea
222                         {       check_fsize($2, FSIZE_L);
223                                 if ((mrg_2&070) == 010 && $3 == 001)
224                                         badoperand();
225                                 emit2((0170000|co_id|mrg_2));
226                                 emit2((0120000|($3<<10)));
227                                 ea_2(SIZE_L, ALT);
228                         }
229         |       FMOVE fsize FPREG ',' FPREG
230                         {       emit2(0170000|co_id);
231                                 emit2(($3<<10)|($5<<7));
232                         }
233         |       FMOVE fsize ea ',' FPREG
234                         {       ch_sz_dreg($2, mrg_2&070);
235                                 emit2((0170000|co_id|mrg_2));
236                                 emit2((0040000|($2<<10)|($5<<7)));
237                                 ea_2(SIZE_L, DTA);
238                         }
239         |       FMOVE fsize FPREG ',' ea
240                         {       ch_sz_dreg($2, mrg_2&070);
241                                 if ($2 == FSIZE_P)
242                                         serror("packed decimal needs k-factor");
243                                 emit2((0170000|co_id|mrg_2));
244                                 emit2((0060000|($2<<10)|($3<<7)));
245                                 ea_2(SIZE_L, DTA|ALT);
246                         }
247         |       FMOVE fsize FPREG ',' ea '{' '#' absexp '}'
248                         {       check_fsize($2, FSIZE_P);
249                                 fit(sfit7($8));
250                                 emit2((0170000|co_id|mrg_2));
251                                 emit2((0066000|($3<<7)|low7($8)));
252                                 ea_2(SIZE_L, MEM|DTA|ALT);
253                         }
254         |       FMOVE fsize FPREG ',' ea '{' DREG '}'
255                         {       check_fsize($2, FSIZE_P);
256                                 emit2((0170000|co_id|mrg_2));
257                                 emit2((0076000|($3<<7)|($7<<4)));
258                                 ea_2(SIZE_L, MEM|DTA|ALT);
259                         }
260         |       FMOVECR fsize '#' absexp ',' FPREG
261                         {       fit(fit7($4));
262                                 check_fsize($2, FSIZE_X);
263                                 emit2(0170000|co_id);
264                                 emit2(056000|($6<<7)|low7($4));
265                         } 
266         |       FMOVEM FSIZE fregs ',' notimmreg
267                         {       check_fsize($2, FSIZE_X);
268                                 if ((mrg_2&070) == 030)
269                                         serror("bad addressing category");
270                                 emit2((0170000|co_id|mrg_2));
271                                 emit2(0160000 |
272                                         (((mrg_2&070)==040 || ($3&04000)) ?
273                                                 $3 :
274                                                 (010000|reverse($3,8))));
275                                 ea_2(SIZE_L, MEM|ALT);
276                         }
277         |       FMOVEM FSIZE notimmreg ',' fregs
278                         {       check_fsize($2, FSIZE_X);
279                                 if ((mrg_2&070) == 040)
280                                         serror("bad addressing category");
281                                 emit2((0170000|co_id|mrg_2));
282                                 emit2((0150000|(($5&04000)?$5:reverse($5,8))));
283                                 ea_2(SIZE_L, MEM);
284                         }
285         |       FMOVEM SIZE fcregs ',' ea
286                         {       checksize($2, 4);
287                                 if ((mrg_2&070) == 1 && $3!= 02000)
288                                         serror("bad addressing category");
289                                 if ((mrg_2 & 070) == 0 &&
290                                     $3 != 02000 && $3 != 04000 && $3 != 010000)
291                                         serror("bad addressing category");
292                                 emit2((0170000|co_id|mrg_2));
293                                 emit2((0120000|$3));
294                                 ea_2(SIZE_L, ALT);
295                         }
296         |       FMOVEM SIZE ea ',' fcregs
297                         {       checksize($2, 4);
298                                 if ((mrg_2&070) == 1 && $5!= 02000)
299                                         serror("bad addressing category");
300                                 if ((mrg_2 & 070) == 0 &&
301                                     $5 != 02000 && $5 != 04000 && $5 != 010000)
302                                         serror("bad addressing category");
303                                 emit2((0170000|co_id|mrg_2));
304                                 emit2((0100000|$5));
305                                 ea_2(SIZE_L, 0);
306                         }
307         |       FDYADIC fsize ea ',' FPREG
308                         {       emit2((0170000|co_id|mrg_2));
309                                 emit2((0040000|($2<<10)|($5<<7)|$1));
310                                 ch_sz_dreg($2, mrg_2&070);
311                                 ea_2(SIZE_L, DTA);
312                         }
313         |       FDYADIC fsize FPREG ',' FPREG
314                         {       check_fsize($2, FSIZE_X);
315                                 emit2(0170000|co_id);
316                                 emit2(($3<<10)|($5<<7)|$1);
317                         }
318         |       FMONADIC fsize ea ',' FPREG
319                         {       emit2((0170000|co_id|mrg_2));
320                                 emit2((0040000|($2<<10)|($5<<7)|$1));
321                                 ch_sz_dreg($2, mrg_2&070);
322                                 ea_2(SIZE_L, DTA);
323                         }
324         |       FMONADIC fsize FPREG ',' FPREG
325                         {       check_fsize($2, FSIZE_X);
326                                 emit2(0170000|co_id);
327                                 emit2(($3<<10)|($5<<7)|$1);
328                         }
329         |       FMONADIC fsize FPREG
330                         {       check_fsize($2, FSIZE_X);
331                                 emit2(0170000|co_id);
332                                 emit2(($3<<10)|($3<<7)|$1);
333                         }
334         |       FSINCOS fsize ea ',' FPREG ':' FPREG
335                         {       emit2(0170000|co_id|mrg_2);
336                                 emit2(0040000|($2<<10)|($7<<7)|$1|$5);
337                                 ea_2(SIZE_L, DTA);
338                         }
339         |       FSINCOS fsize FPREG ',' FPREG ':' FPREG
340                         {       check_fsize($2, FSIZE_X);
341                                 emit2(0170000|co_id);
342                                 emit2(($3<<10)|($7<<7)|$1|$5);
343                         }
344         |       FBCC expr
345                         {       fbranch($1, $2);}
346         |       FDBCC DREG ',' expr
347                         {       emit2(0170110|co_id|$2);
348                                 emit2($1);
349                                 $4.val -= DOTVAL;
350                                 fit(fitw($4.val));
351 #ifdef RELOCATION
352                                 newrelo($4.typ, RELPC|RELO2|RELBR|RELWR);
353 #endif
354                                 emit2(loww($4.val));
355                         }
356         |       FNOP
357                         {       emit2(0170200|co_id);
358                                 emit2(0);
359                         }
360         |       FSCC ea
361                         {       emit2(0170100|co_id|mrg_2);
362                                 emit2($1);
363                                 ea_2(SIZE_B, DTA|ALT);
364                         }
365         |       FTST fsize ea
366                         {       emit2((0170000|co_id|mrg_2));
367                                 emit2((0040072|($2<<10)));
368                                 ch_sz_dreg($2, mrg_2&070);
369                                 ea_2(SIZE_L, DTA);
370                         }
371         |       FTST fsize FPREG
372                         {       check_fsize($2, FSIZE_X);
373                                 emit2(0170000|co_id);
374                                 emit2(($3<<10)|072);
375                         }
376         |       FSAVRES ea
377                         {       if ((mrg_2&070) == ($1&070))
378                                         badoperand();
379                                 emit2((0170000|co_id|($1&0700)|mrg_2));
380                                 ea_2(0, $1&07);
381                         }
382         |       FTRAPCC
383                         {       emit2(0170174|co_id);
384                                 emit2($1);
385                         }
386         |       FTRAPCC SIZE imm
387                         {       checksize($2, 2|4);
388                                 emit2((0170170|co_id|($2==SIZE_L?03:02)));
389                                 emit2($1);
390                                 ea_2($2,0);
391                         }
392         ;
393 fregs   :       DREG
394                         {       $$ = 04000 | $1 << 4; }
395         |       frlist
396         ;
397 frlist  :       frrange
398         |       frlist '/' frrange
399                         {       $$ = $1 | $3;}
400         ;
401 frrange :       FPREG
402                         {       $$ = 1 << $1; }
403         |       FPREG '-' FPREG
404                         {       if ($1 > $3)
405                                         badoperand();
406                                 for ($$ = 0; $1 <= $3; $1++)
407                                         $$ |= (1 << $1);
408                         }
409         ;
410 fcregs  :       FPCR
411                         {       $$ = $1 << 10; }
412         |       fcregs '/' FPCR
413                         {       $$ = $1 | ($3 << 10); }
414         ;
415 fsize   :       /*      empty */
416                         {       $$ = FSIZE_X; }
417         |       SIZE
418                         {       if ($1 == SIZE_L)
419                                         $$ = FSIZE_L;
420                                 else if ($1 == SIZE_W)
421                                         $$ = FSIZE_W;
422                                 else    $$ = FSIZE_B;
423                         }
424         |       FSIZE
425         ;