Pristine Ack-5.5
[Ack-5.5.git] / mach / proto / as / comm7.c
1 /* $Id: comm7.c,v 2.21 1994/06/24 13:22:14 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 /* @(#)comm7.c  1.10 */
7 /*
8  * miscellaneous
9  */
10
11 #include        "comm0.h"
12 #include        "comm1.h"
13 #include        "y.tab.h"
14
15 valu_t
16 load(ip)
17 register item_t *ip;
18 {
19 #ifdef ASLD
20         register typ;
21
22         typ = ip->i_type & S_TYP;
23         if ((typ -= S_MIN) < 0)         /* S_UND or S_ABS */
24                 return(ip->i_valu);
25         return(ip->i_valu + sect[typ].s_base);
26 #else
27         if ((ip->i_type & S_TYP) == S_UND || (ip->i_type & S_COM)) {
28                 if (pass == PASS_3) {
29                         if (relonami != 0)
30                                 serror("relocation error");
31                         relonami = ip->i_valu+1;
32                 }
33                 return(0);
34         }
35         return(ip->i_valu);
36 #endif
37 }
38
39 store(ip, val)
40 register item_t *ip;
41 valu_t val;
42 {
43 #ifdef ASLD
44         register typ;
45
46         typ = ip->i_type & S_TYP;
47         if ((typ -= S_MIN) >= 0)
48                 val -= sect[typ].s_base;
49 #else
50         if ((ip->i_type & S_TYP) == S_UND)
51                 return(0);
52 #endif
53         assert(pass != PASS_3 || (ip->i_type & S_VAR) || ip->i_valu == val);
54         ip->i_valu = val;
55         return(1);
56 }
57
58 char *
59 remember(s)
60 register char *s;
61 {
62         register char *p;
63         register n;
64         static nleft = 0;
65         static char *next;
66
67         p = s;
68         n = 0;
69         do
70                 n++;
71         while (*p++);
72         if ((nleft -= n) < 0) {
73                 next = malloc(MEMINCR);
74                 if (next == 0)
75                         fatal("out of memory");
76                 nleft = (MEMINCR / sizeof(char)) - n;
77                 assert(nleft >= 0);
78         }
79         p = next;
80         while (*p++ = *s++)
81                 ;
82         s = next;
83         next = p;
84         return(s);
85 }
86
87 combine(typ1, typ2, op)
88 register typ1, typ2;
89 {
90         switch (op) {
91         case '+':
92                 if (typ1 == S_ABS)
93                         return(typ2);
94                 if (typ2 == S_ABS)
95                         return(typ1);
96                 break;
97         case '-':
98                 if (typ2 == S_ABS)
99                         return(typ1);
100                 if ((typ1 & ~S_DOT) == (typ2 & ~S_DOT) && typ1 != S_UND)
101                         return(S_ABS|S_VAR);
102                 break;
103         case '>':
104                 if (typ1 == S_ABS && typ2 == S_ABS)
105                         return(S_ABS);
106                 if (
107                     ((typ1 & ~S_DOT) == (typ2 & ~S_DOT) && typ1 != S_UND)
108                     || (typ1 == S_ABS)
109                     || (typ2 == S_ABS)
110                    )
111                         return(S_ABS|S_VAR);
112                 break;
113         default:
114                 if (typ1 == S_ABS && typ2 == S_ABS)
115                         return(S_ABS);
116                 break;
117         }
118         if (pass != PASS_1)
119                 serror("illegal operator");
120         return(S_UND);
121 }
122
123 #ifdef LISTING
124 printx(ndig, val)
125 valu_t val;
126 {
127         static char buf[8];
128         register char *p;
129         register c, n;
130
131         p = buf; n = ndig;
132         do {
133                 *p++ = (int) val & 017;
134                 val >>= 4;
135         } while (--n);
136         do {
137                 c = "0123456789ABCDEF"[*--p];
138                 putchar(c);
139         } while (p > buf);
140         return(ndig);
141 }
142 #endif
143
144 #ifdef LISTING
145 listline(textline)
146 {
147         register c;
148
149         if ((listflag & 4) && (c = getc(listfile)) != '\n' && textline) {
150                 if (listcolm >= 24)
151                         printf(" \\\n\t\t\t");
152                 else
153                         do {
154                                 putchar('\t');
155                                 listcolm += 8;
156                         } while (listcolm < 24);
157                 do {
158                         assert(c != EOF);
159                         putchar(c);
160                 } while ((c = getc(listfile)) != '\n');
161         }
162         if (listflag & 7) {
163                 putchar('\n');
164                 fflush(stdout);
165         }
166         listeoln = 1;
167         listcolm = 0;
168         listflag = listtemp;
169 }
170 #endif /* LISTING */
171
172 /* ---------- code optimization ---------- */
173
174 #ifdef THREE_PASS
175 #define PBITTABSZ       128
176 static char *pbittab[PBITTABSZ];
177
178 small(fitsmall, gain)
179 {
180         register bit;
181         register char *p;
182
183         if (DOTSCT == NULL)
184                 nosect();
185         if (bflag)
186                 return(0);
187         if (nbits == BITCHUNK) {
188                 bitindex++;
189                 nbits = 0;
190                 if (bitindex == PBITTABSZ) {
191                         static int w_given;
192                         if (pass == PASS_1 && ! w_given) {
193                                 w_given = 1;
194                                 warning("bit table overflow");
195                         }
196                         return(0);
197                 }
198                 if (pbittab[bitindex] == 0 && pass == PASS_1) {
199                         if ((pbittab[bitindex] = calloc(MEMINCR, 1)) == 0) {
200                                 static int w2_given;
201
202                                 if (!w2_given) {
203                                         w2_given = 1;
204                                         warning("out of space for bit table");
205                                 }
206                         }
207                 }
208                 if (pbittab[bitindex] == 0)
209                         return (0);
210         }
211         bit = 1 << (nbits&7);
212         p = pbittab[bitindex]+(nbits>>3);
213         nbits++;
214         switch (pass) {
215         case PASS_1:
216                 return(0);
217         case PASS_2:
218                 if (fitsmall) {
219                         DOTGAIN += gain;
220                         *p |= bit;
221                 }
222                 return(fitsmall);
223         case PASS_3:
224                 assert(fitsmall || (*p & bit) == 0);
225                 return(*p & bit);
226         }
227         /*NOTREACHED*/
228 }
229 #endif
230
231 /* ---------- output ---------- */
232
233 emit1(arg)
234 {
235         static int olddottyp = -1;
236 #ifdef LISTING
237         if (listeoln) {
238                 if (listflag & 1) {
239                         listcolm += printx(VALWIDTH, (valu_t)DOTVAL);
240                         listcolm++;
241                         putchar(' ');
242                 }
243                 listeoln = 0;
244         }
245         if (listflag & 2)
246                 listcolm += printx(2, (valu_t) arg);
247 #endif
248         switch (pass) {
249         case PASS_1:
250                 if (DOTSCT == NULL)
251                         nosect();
252                 /* no break */
253         case PASS_2:
254                 DOTSCT->s_zero = 0;
255                 break;
256         case PASS_3:
257                 if (DOTTYP != olddottyp) {
258                         wr_outsect(DOTTYP-S_MIN);
259                         olddottyp = DOTTYP;
260                 }
261                 while (DOTSCT->s_zero) {
262                         wr_putc(0);
263                         DOTSCT->s_zero--;
264                 }
265                 wr_putc(arg);
266                 break;
267         }
268         DOTVAL++;
269 }
270
271 emit2(arg)
272 int arg;
273 {
274 #ifdef BYTES_REVERSED
275         emit1((arg>>8)); emit1(arg);
276 #else
277         emit1(arg); emit1((arg>>8));
278 #endif
279 }
280
281 emit4(arg)
282 long arg;
283 {
284 #ifdef WORDS_REVERSED
285         emit2((int)(arg>>16)); emit2((int)(arg));
286 #else
287         emit2((int)(arg)); emit2((int)(arg>>16));
288 #endif
289 }
290
291 emitx(val, n)
292 valu_t val;
293 int n;
294 {
295         switch (n) {
296         case 1:
297                 emit1((int)val); break;
298         case 2:
299 #ifdef BYTES_REVERSED
300                 emit1(((int)val>>8)); emit1((int)val);
301 #else
302                 emit1((int)val); emit1(((int)val>>8));
303 #endif
304                 break;
305         case 4:
306 #ifdef WORDS_REVERSED
307                 emit2((int)(val>>16)); emit2((int)(val));
308 #else
309                 emit2((int)(val)); emit2((int)(val>>16));
310 #endif
311                 break;
312         default:
313                 assert(0);
314         }
315 }
316
317 emitstr(zero)
318 {
319         register i;
320         register char *p;
321
322         p = stringbuf;
323         i = stringlen;
324         while (--i >= 0)
325                 emit1(*p++);
326         if (zero)
327                 emit1(0);
328 }
329
330 /* ---------- Error checked file I/O  ---------- */
331
332 ffreopen(s, f)
333 char *s;
334 FILE *f;
335 {
336         if (freopen(s, "r", f) == NULL)
337                 fatal("can't reopen %s", s);
338 }
339
340 FILE *
341 ffcreat(s)
342 char *s;
343 {
344         FILE *f;
345
346         if ((f = fopen(s, "w")) == NULL)
347                 fatal("can't create %s", s);
348         return(f);
349 }
350
351 #ifndef TMPDIR
352 #define TMPDIR "/tmp"
353 #endif
354 char *tmp_dir = TMPDIR;
355
356 FILE *
357 fftemp(path, tail)
358 char *path, *tail;
359 {
360         register char *dir;
361
362         if ((dir = getenv("TMPDIR")) == NULL)
363                 dir = tmp_dir;
364         sprintf(path, "%s/%s", dir, tail);
365         return(ffcreat(mktemp(path)));
366 }
367
368 /* ---------- Error handling ---------- */
369
370 /*VARARGS*/
371 yyerror(){}             /* we will do our own error printing */
372
373 nosect()
374 {
375         fatal("no sections");
376 }
377
378 wr_fatal()
379 {
380         fatal("write error");
381 }
382
383 /* VARARGS1 */
384 fatal(s, a1, a2, a3, a4)
385 char *s;
386 {
387         nerrors++;
388         diag(" (fatal)\n", s, a1, a2, a3, a4);
389         stop();
390 }
391
392 #if DEBUG == 2
393 assert2(file, line)
394 char *file;
395 {
396         fatal("assertion failed (%s, %d)", file, line);
397 }
398 #endif
399
400 #if DEBUG == 1
401 assert1()
402 {
403         diag(" (fatal)\n", "assertion failed");
404         abort();
405 }
406 #endif
407
408 /* VARARGS1 */
409 serror(s, a1, a2, a3, a4)
410 char *s;
411 {
412         nerrors++;
413         diag("\n", s, a1, a2, a3, a4);
414 }
415
416 /* VARARGS1 */
417 warning(s, a1, a2, a3, a4)
418 char *s;
419 {
420         diag(" (warning)\n", s, a1, a2, a3, a4);
421 }
422
423 /* VARARGS1 */
424 diag(tail, s, a1, a2, a3, a4)
425 char *tail, *s;
426 {
427         fflush(stdout);
428         if (modulename)
429                 fprintf(stderr, "\"%s\", line %ld: ", modulename, lineno);
430         else
431                 fprintf(stderr, "%s: ", progname);
432         fprintf(stderr, s, a1, a2, a3, a4);
433         fprintf(stderr, tail);
434 }
435
436 nofit()
437 {
438         if (pass == PASS_3)
439                 warning("too big");
440 }