Pristine Ack-5.5
[Ack-5.5.git] / mach / 6809 / as / mach4.c
1 #define RCSID4 "$Id: mach4.c,v 3.5 1994/06/24 12:56:27 ceriel Exp $"
2
3 /*
4  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
5  * See the copyright notice in the ACK home directory, in the file "Copyright".
6  *
7  */
8
9 /*
10  * Motorola 6809 parsing rules
11  */
12
13 operation
14         :       SETDP expr
15                         {       dpvalue = $2.val;}
16         |
17                 NOARG
18                         {       emit1or2($1);}
19         |
20                 BRANCH expr
21                         {       branch($1,$2);}
22         |
23                 LBRNCH expr
24                         {       emit1(0x10); emit1($1);
25                                 $2.val -= (DOTVAL+2);
26 #ifdef RELOCATION
27                                 if (rflag != 0 && PASS_RELO)
28                                         newrelo($2.typ, RELPC|RELO2|RELBR);
29 #endif
30                                 emit2($2.val);
31                         }
32         |
33                 SBRNCH expr
34                         {       emit1($1);
35                                 $2.val -= (DOTVAL+2);
36 #ifdef RELOCATION
37                                 if (rflag != 0 && PASS_RELO)
38                                         newrelo($2.typ, RELPC|RELO2|RELBR);
39 #endif
40                                 emit2($2.val);
41                         }
42         |
43                 IMMED '#' expr
44                         {       emit1($1);
45 #ifdef RELOCATION
46                                 if (rflag != 0 && PASS_RELO)
47                                         newrelo($3.typ, RELO1);
48 #endif
49                                 emit1($3.val);
50                         }
51         |
52                 XOP '#' expr
53                         {       emit1or2($1 - 0x20);
54                                 switch ($1 & 0x0F) {
55                                 case 0x03:
56                                 case 0x0C:
57                                 case 0x0E:
58 #ifdef RELOCATION
59                                         if (rflag != 0 && PASS_RELO)
60                                                 newrelo($3.typ, RELO2|RELBR);
61 #endif
62                                         emit2($3.val);
63                                         break;
64                                 default:
65 #ifdef RELOCATION
66                                         if (rflag != 0 && PASS_RELO)
67                                                 newrelo($3.typ, RELO1);
68 #endif
69                                         emit1($3.val);
70                                         break;
71                                 }
72                         }
73         |
74                 XOP '<' expr
75                         {       if (0 <= $1 && $1 < 0x80)
76                                         emit1(($1-0x10) & 0x3F);
77                                 else
78                                         emit1or2($1 - 0x10);
79 #ifdef RELOCATION
80                                 if (rflag != 0 && PASS_RELO)
81                                         newrelo($3.typ, RELO1);
82 #endif
83                                 emit1($3.val);
84                         }
85         |
86                 XOP '>' expr
87                         {       emit1or2($1 + 0x10);
88 #ifdef RELOCATION
89                                 if (rflag != 0 && PASS_RELO)
90                                         newrelo($3.typ, RELO2|RELBR);
91 #endif
92                                 emit2($3.val);
93                         }
94         |
95                 STACK reglist
96                         {       emit1($1); emit1($2);}
97         |
98                 TWOREG REG ',' REG
99                         {
100                                 emit1($1);
101                                 emit1($2 << 4 | $4);
102                         }
103         |
104                 XOP REG
105                         {       switch ($2) {
106                                 case A: emit1($1 - 0x20);
107                                         break;
108                                 case B: emit1($1 - 0x10);
109                                         break;
110                                 default:serror("register error");
111                                 }
112                         }
113         |
114                 XOP expr ',' REG
115                         {       emit1or2($1);
116                                 offset($4,$2,0);
117                         }
118         |
119                 XOP '(' expr ',' REG ')'
120                         {       emit1or2($1);
121                                 offset($5,$3,0x10);
122                         }
123         |
124                 XOP '(' expr ')'
125                         {       emit1or2($1);
126                                 emit1(0x9F);
127 #ifdef RELOCATION
128                                 if (rflag != 0 && PASS_RELO)
129                                         newrelo($3.typ, RELO2|RELBR);
130 #endif
131                                 emit2($3.val);
132                         }
133         |
134                 XOP xmode
135                         {       emit1or2($1);
136                                 emit1($2);
137                         }
138         |
139                 XOP '(' xmode ')'
140                         {       if (($3 & 0x8D) == 0x80)
141                                         serror("invalid index mode");
142                                 emit1or2($1);
143                                 emit1($3 + 0x10);
144                         }
145         |
146                 XOP expr
147                         {       if (($2.typ & S_TYP) == S_ABS &&
148                                     ((unsigned)$2.val >> 8) == dpvalue
149                                 ) {
150                                         if (0 <= $1 && $1 < 0x80)
151                                                 emit1(($1-0x20) & 0x3F);
152                                         else
153                                                 emit1or2($1 - 0x10);
154                                         emit1($2.val);
155                                 } else {
156                                         emit1or2($1 + 0x10);
157 #ifdef RELOCATION
158                                         if (rflag != 0 && PASS_RELO)
159                                                 newrelo($2.typ, RELO2|RELBR);
160 #endif
161                                         emit2($2.val);
162                                 }
163                         }
164         ;
165 reglist :       ALL
166         |       REG
167                         { if (($$ = regbit[$1]) < 0) serror("register error");}
168         |
169                 reglist ',' REG
170                         {       register i;
171                                 if ((i = regbit[$3]) < 0 || ($1 & i) != 0)
172                                         serror("register error");
173                                 $$ = $1 | i;
174                         }
175         ;
176 xyus    :       REG
177                         { if (($$ = regno($1)) < 0) serror("register error");}
178         ;
179 xmode   :       ',' xyus '+' '+'
180                         {       $$ = 0x81 + $2;}
181         |
182                 ',' xyus '+'
183                         {       $$ = 0x80 + $2;}
184         |
185                 ',' xyus
186                         {       $$ = 0x84 + $2;}
187         |
188                 ',' '-' '-' xyus
189                         {       $$ = 0x83 + $4;}
190         |
191                 ',' '-' xyus
192                         {       $$ = 0x82 + $3;}
193         |
194                 REG ',' xyus
195                         {       switch($1) {
196                                 case A: $$ = 0x86 + $3; break;
197                                 case B: $$ = 0x85 + $3; break;
198                                 case D: $$ = 0x8B + $3; break;
199                                 default: serror("register error");
200                                 }
201                         }
202         ;