Pristine Ack-5.5
[Ack-5.5.git] / mach / i86 / as / mach5.c
1 /*
2  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3  * See the copyright notice in the ACK home directory, in the file "Copyright".
4  */
5 #define RCSID5 "$Id: mach5.c,v 3.8 1994/06/28 14:41:17 ceriel Exp $"
6
7 /*
8  * INTEL 8086 special routines
9  */
10
11 ea_1(param) {
12
13         if ((mrg_1 & 070) || (param & ~070)) {
14                 serror("bad operand");
15         }
16         emit1(mrg_1 | param);
17         switch(mrg_1 >> 6) {
18         case 0:
19                 if (mrg_1 == 6 || (mrg_1 & 040)) {
20 #ifdef RELOCATION
21                         RELOMOVE(relonami, rel_1);
22                         newrelo(exp_1.typ, RELO2);
23 #endif
24                         emit2(exp_1.val);
25                 }
26                 break;
27         case 1:
28 #ifdef RELOCATION
29                 RELOMOVE(relonami, rel_1);
30                 newrelo(exp_1.typ, RELO1);
31 #endif
32                 emit1(exp_1.val);
33                 break;
34         case 2:
35 #ifdef RELOCATION
36                 RELOMOVE(relonami, rel_1);
37                 newrelo(exp_1.typ, RELO2);
38 #endif
39                 emit2(exp_1.val);
40                 break;
41         }
42 }
43
44 ea_2(param) {
45
46         mrg_1 = mrg_2;
47         exp_1 = exp_2;
48         RELOMOVE(rel_1, rel_2);
49         ea_1(param);
50 }
51
52 reverse() {
53         register m, r; expr_t e;
54
55         m = mrg_1; mrg_1 = mrg_2; mrg_2 = m;
56         e = exp_1; exp_1 = exp_2; exp_2 = e;
57 #ifndef ASLD
58         r = rel_1; rel_1 = rel_2; rel_2 = r;
59 #endif
60 }
61
62 badsyntax() {
63
64         serror("bad operands");
65 }
66
67 regsize(sz) register sz; {
68         register bit;
69
70         sz <<= 3;
71         bit = 010;
72         sz &= bit;
73         if ((mrg_1 >= 0300 && (mrg_1 & bit) != sz) ||
74             (mrg_2 >= 0300 && (mrg_2 & bit) != sz))
75                 serror("register error");
76         mrg_1 &= ~bit;
77         mrg_2 &= ~bit;
78 }
79
80 indexed() {
81         int sm1, sm2;
82
83         if (mrg_2 & ~7)
84                 serror("register error");
85         sm1 = exp_2.typ == S_ABS && fitb((short)(exp_2.val));
86         if (sm1) {
87                 sm2 = exp_2.val == 0 && mrg_2 != 6;
88         }
89         else sm2 = 0;
90         if (small(sm1, 1)) {
91                 if (small(sm2, 1)) {
92                 }
93                 else mrg_2 |= 0100;
94         }
95         else {
96                 if (small(0, 1)) {}
97                 mrg_2 |= 0200;
98         }
99 }
100
101 branch(opc,exp) register opc; expr_t exp; {
102         register sm,dist;
103         int saving = opc == 0353 ? 1 : 3;
104
105         dist = exp.val - (DOTVAL + 2);
106         if (pass == PASS_2 && dist > 0 && !(exp.typ & S_DOT))
107                 dist -= DOTGAIN;
108         sm = dist > 0 ? fitb(dist-saving) : fitb(dist);
109         if ((exp.typ & ~S_DOT) != DOTTYP)
110                 sm = 0;
111         if ((opc & 0370) == 0340) {
112                 fit(sm);
113                 sm = 1;
114         } else {
115                 if ((sm = small(sm,saving)) == 0) {
116                         if (opc != 0353) {
117                                 emit1(opc^1);
118                                 emit1(3);
119                                 dist -= 2;
120                         }
121                         opc = 0351;
122                         dist--;
123                 }
124         }
125         emit1(opc);
126         if (sm == 0) {
127 #ifdef RELOCATION
128                 newrelo(exp.typ, RELPC | RELO2);
129 #endif
130                 emit2(dist);
131         } else
132                 emit1(dist);
133 }
134
135 pushop(opc) register opc; {
136
137         regsize(1);
138         if (mrg_1 & 020) {
139                 if ( (mrg_1&3) == 1 && opc==1 ) badsyntax() ;
140                 emit1(6 | opc | (mrg_1&3)<<3);
141         } else if (mrg_1 >= 0300) {
142                 emit1(0120 | opc<<3 | (mrg_1&7));
143         } else if (opc == 0) {
144                 if (mrg_1 & 040) {      /* 070 ??? */
145                         if (small(exp_1.typ == S_ABS && fitb((short)exp_1.val),1)) {
146                                 emit1(0152);
147                                 emit1((int) exp_1.val);
148                         } else {
149                                 emit1(0150);
150                                 RELOMOVE(relonami, rel_1);
151 #ifdef RELOCATION
152                                 newrelo(exp_1.typ, RELO2);
153                                 emit2((int) exp_1.val);
154 #endif
155                         }
156                 } else {
157                         emit1(0377); ea_1(6<<3);
158                 }
159         } else {
160                 emit1(0217); ea_1(0<<3);
161         }
162 }
163
164 addop(opc) register opc; {
165
166         regsize(opc);
167         if (mrg_2 >= 0300) {
168                 emit1(opc); ea_1((mrg_2&7)<<3);
169         } else if ((mrg_2 & 040) && mrg_1 == 0300) {
170                 emit1(opc | 4);
171 #ifdef RELOCATION
172                 RELOMOVE(relonami, rel_2);
173                 newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
174 #endif
175                 emitx(exp_2.val, (opc&1)+1);
176         } else if (mrg_2 & 040) {
177                 if ((opc&1) == 0) {
178                         emit1(0200);
179                 } else {
180                         int sm = exp_2.typ == S_ABS && fitb((short)exp_2.val) &&
181                                 opc != 011 && opc != 041 && opc != 061;
182                         if (small(sm, 1)) {
183                                 emit1(0203); opc &= ~1;
184                         }
185                         else emit1(0201);
186                 }
187                 ea_1(opc & 070);
188 #ifdef RELOCATION
189                         RELOMOVE(relonami, rel_2);
190                         newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
191 #endif
192                 emitx(exp_2.val, (opc&1)+1);
193         } else if (mrg_1 >= 0300) {
194                 emit1(opc | 2);
195                 ea_2((mrg_1&7)<<3);
196         } else
197                 badsyntax();
198 }
199
200 rolop(opc) register opc; {
201         register cmrg;
202
203         cmrg = mrg_2;
204         mrg_2 = mrg_1;
205         regsize(opc);
206         if (cmrg == 0301) {
207                 emit1(0322 | (opc&1)); ea_1(opc&070);
208         } else if (cmrg & 040) {
209                 if (small(exp_2.val == 1, 1)) {
210                         emit1(0320 | (opc&1)); ea_1(opc&070);
211                 } else {
212                         fit(fitb(exp_2.val));
213                         emit1(0300|(opc&1)); ea_1(opc&070);
214                         emit1((int)exp_2.val);
215                 }
216         } else
217                 badsyntax();
218 }
219
220 incop(opc) register opc; {
221
222         regsize(opc);
223         if ((opc&1) && mrg_1>=0300) {
224                 emit1(0100 | (opc&010) | (mrg_1&7));
225         } else {
226                 emit1(0376 | (opc&1));
227                 ea_1(opc & 010);
228         }
229 }
230
231 callop(opc) register opc; {
232
233         regsize(1);
234         if (mrg_1 & 040) {
235                 if (opc == (040+(0351<<8))) {
236                         RELOMOVE(relonami, rel_1);
237                         branch(0353,exp_1);
238                 } else {
239                         exp_1.val -= (DOTVAL+3);
240                         emit1(opc>>8);
241 #ifdef RELOCATION
242                         RELOMOVE(relonami, rel_1);
243                         newrelo(exp_1.typ, RELPC | RELO2);
244 #endif
245                         emit2(exp_1.val);
246                 }
247         } else {
248                 emit1(0377); ea_1(opc&070);
249         }
250 }
251
252 xchg(opc) register opc; {
253
254         regsize(opc);
255         if (mrg_2 == 0300 || mrg_1 < 0300)
256                 reverse();
257         if (opc == 1 && mrg_1 == 0300 && mrg_2 >= 0300) {
258                 emit1(0220 | (mrg_2&7));
259         } else if (mrg_1 >= 0300) {
260                 emit1(0206 | opc); ea_2((mrg_1&7)<<3);
261         } else
262                 badsyntax();
263 }
264
265 test(opc) register opc; {
266
267         regsize(opc);
268         if ((mrg_1 & 040) || mrg_2 >= 0300)
269                 reverse();
270         if ((mrg_2 & 040) && mrg_1 == 0300) {
271                 emit1(0250 | opc);
272 #ifdef RELOCATION
273                         RELOMOVE(relonami, rel_2);
274                         newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
275 #endif
276                 emitx(exp_2.val, (opc&1)+1);
277         } else if (mrg_2 & 040) {
278                 emit1(0366 | opc);
279                 ea_1(0<<3);
280 #ifdef RELOCATION
281                         RELOMOVE(relonami, rel_2);
282                         newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
283 #endif
284                 emitx(exp_2.val, (opc&1)+1);
285         } else if (mrg_1 >= 0300) {
286                 emit1(0204 | opc); ea_2((mrg_1&7)<<3);
287         } else
288                 badsyntax();
289 }
290
291 mov(opc) register opc; {
292
293         regsize(opc);
294         if (mrg_1 & 020) {
295                 emit1(0216); ea_2((mrg_1&3)<<3);
296         } else if (mrg_2 & 020) {
297                 emit1(0214); ea_1((mrg_2&3)<<3);
298         } else if (mrg_2 & 040) {
299                 if (mrg_1 >= 0300) {
300                         emit1(0260 | opc<<3 | (mrg_1&7)); 
301 #ifdef RELOCATION
302                         RELOMOVE(relonami, rel_2);
303                         newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
304 #endif
305                         emitx(exp_2.val, (opc&1)+1);
306                 } else {
307                         emit1(0306 | opc); ea_1(0<<3); 
308 #ifdef RELOCATION
309                         RELOMOVE(relonami, rel_2);
310                         newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
311 #endif
312                         emitx(exp_2.val, (opc&1)+1);
313                 }
314         } else if (mrg_2 == 0300 && mrg_1 == 6) {
315                 emit1(0242 | opc);
316 #ifdef RELOCATION
317                 RELOMOVE(relonami, rel_1);
318                 newrelo(exp_1.typ, RELO2);
319 #endif
320                 emit2(exp_1.val);
321         } else if (mrg_1 == 0300 && mrg_2 == 6) {
322                 emit1(0240 | opc);
323 #ifdef RELOCATION
324                 RELOMOVE(relonami, rel_2);
325                 newrelo(exp_2.typ, RELO2);
326 #endif
327                 emit2(exp_2.val);
328         } else if (mrg_2 >= 0300) {
329                 emit1(0210 | opc); ea_1((mrg_2&7)<<3);
330         } else if (mrg_1 >= 0300) {
331                 emit1(0212 | opc); ea_2((mrg_1&7)<<3);
332         } else {
333                 badsyntax();
334         }
335 }
336
337 imul(opc)
338         int opc;
339 {
340         regsize(opc);
341         if (exp_2.typ != S_ABS || ((mrg_2 & 040) == 0)) {
342                 serror("bad operand");
343         } else {
344                 if (small(exp_2.typ == S_ABS && fitb((short)exp_2.val),1)) {
345                         emit1(0153);
346                         ea_1((mrg_2&7)<<3);
347                         emit1((int)exp_2.val);
348                 } else {
349                         emit1(0151);
350                         ea_1((mrg_2&7)<<3);
351                         RELOMOVE(relonami, rel_2);
352 #ifdef RELOCATION
353                         newrelo(exp_2.typ, RELO2);
354                         emit2((int) exp_2.val);
355 #endif
356                 }
357         }
358 }