BSD 4_3 release
[unix-history] / usr / src / usr.bin / f77 / src / f77pass1 / misc.c
CommitLineData
be58de96
KM
1/*
2 * Copyright (c) 1980 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
7#ifndef lint
95f51977 8static char sccsid[] = "@(#)misc.c 5.2 (Berkeley) 1/7/86";
be58de96
KM
9#endif not lint
10
11/*
12 * misc.c
13 *
14 * Miscellaneous routines for the f77 compiler, 4.2 BSD.
15 *
16 * University of Utah CS Dept modification history:
17 *
18 * $Log: misc.c,v $
1792af96
DS
19 * Revision 5.2 85/12/18 00:35:08 donn
20 * Prevent core dumps for peculiar statement numbers.
21 *
22 * Revision 5.1 85/08/10 03:48:29 donn
23 * 4.3 alpha
24 *
be58de96
KM
25 * Revision 3.1 84/10/13 01:53:26 donn
26 * Installed Jerry Berkman's version; added UofU comment header.
27 *
28 */
29
30#include "defs.h"
31
32
33
34cpn(n, a, b)
35register int n;
36register char *a, *b;
37{
38while(--n >= 0)
39 *b++ = *a++;
40}
41
42
43
44eqn(n, a, b)
45register int n;
46register char *a, *b;
47{
48while(--n >= 0)
49 if(*a++ != *b++)
50 return(NO);
51return(YES);
52}
53
54
55
56
57
58
59
60cmpstr(a, b, la, lb) /* compare two strings */
61register char *a, *b;
62ftnint la, lb;
63{
64register char *aend, *bend;
65aend = a + la;
66bend = b + lb;
67
68
69if(la <= lb)
70 {
71 while(a < aend)
72 if(*a != *b)
73 return( *a - *b );
74 else
75 { ++a; ++b; }
76
77 while(b < bend)
78 if(*b != ' ')
79 return(' ' - *b);
80 else
81 ++b;
82 }
83
84else
85 {
86 while(b < bend)
87 if(*a != *b)
88 return( *a - *b );
89 else
90 { ++a; ++b; }
91 while(a < aend)
92 if(*a != ' ')
93 return(*a - ' ');
94 else
95 ++a;
96 }
97return(0);
98}
99
100
101
102
103
104chainp hookup(x,y)
105register chainp x, y;
106{
107register chainp p;
108
109if(x == NULL)
110 return(y);
111
112for(p = x ; p->nextp ; p = p->nextp)
113 ;
114p->nextp = y;
115return(x);
116}
117
118
119
120struct Listblock *mklist(p)
121chainp p;
122{
123register struct Listblock *q;
124
125q = ALLOC(Listblock);
126q->tag = TLIST;
127q->listp = p;
128return(q);
129}
130
131
132chainp mkchain(p,q)
133register tagptr p;
134register chainp q;
135{
136register chainp r;
137
138if(chains)
139 {
140 r = chains;
141 chains = chains->nextp;
142 }
143else
144 r = ALLOC(Chain);
145
146r->datap = p;
147r->nextp = q;
148return(r);
149}
150
151
152
153char * varstr(n, s)
154register int n;
155register char *s;
156{
157register int i;
158static char name[XL+1];
159
160for(i=0; i<n && *s!=' ' && *s!='\0' ; ++i)
161 name[i] = *s++;
162
163name[i] = '\0';
164
165return( name );
166}
167
168
169
170
171char * varunder(n, s)
172register int n;
173register char *s;
174{
175register int i;
176static char name[XL+1];
177
178for(i=0; i<n && *s!=' ' && *s!='\0' ; ++i)
179 name[i] = *s++;
180
181#if TARGET != GCOS
182name[i++] = '_';
183#endif
184
185name[i] = '\0';
186
187return( name );
188}
189
190
191
192
193
194char * nounder(n, s)
195register int n;
196register char *s;
197{
198register int i;
199static char name[XL+1];
200
201for(i=0; i<n && *s!=' ' && *s!='\0' ; ++s)
202 if(*s != '_')
203 name[i++] = *s;
204
205name[i] = '\0';
206
207return( name );
208}
209
210
211
212char *copyn(n, s)
213register int n;
214register char *s;
215{
216register char *p, *q;
217
218p = q = (char *) ckalloc(n);
219while(--n >= 0)
220 *q++ = *s++;
221return(p);
222}
223
224
225
226char *copys(s)
227char *s;
228{
229return( copyn( strlen(s)+1 , s) );
230}
231
232
233
234ftnint convci(n, s)
235register int n;
236register char *s;
237{
238ftnint sum;
239ftnint digval;
240sum = 0;
241while(n-- > 0)
242 {
243 if (sum > MAXINT/10 ) {
244 err("integer constant too large");
245 return(sum);
246 }
247 sum *= 10;
248 digval = *s++ - '0';
249#if (TARGET != VAX)
250 sum += digval;
251#endif
252#if (TARGET == VAX)
253 if ( MAXINT - sum >= digval ) {
254 sum += digval;
255 } else {
256 /* KLUDGE. On VAXs, MININT is (-MAXINT)-1 , i.e., there
257 is one more neg. integer than pos. integer. The
258 following code returns MININT whenever (MAXINT+1)
259 is seen. On VAXs, such statements as: i = MININT
260 work, although this generates garbage for
261 such statements as: i = MPLUS1 where MPLUS1 is MAXINT+1
262 or: i = 5 - 2147483647/2 .
263 The only excuse for this kludge is it keeps all legal
264 programs running and flags most illegal constants, unlike
265 the previous version which flaged nothing outside data stmts!
266 */
267 if ( n == 0 && MAXINT - sum + 1 == digval ) {
268 warn("minimum negative integer compiled - possibly bad code");
269 sum = MININT;
270 } else {
271 err("integer constant too large");
272 return(sum);
273 }
274 }
275#endif
276 }
277return(sum);
278}
279
280char *convic(n)
281ftnint n;
282{
283static char s[20];
284register char *t;
285
286s[19] = '\0';
287t = s+19;
288
289do {
290 *--t = '0' + n%10;
291 n /= 10;
292 } while(n > 0);
293
294return(t);
295}
296
297
298
299double convcd(n, s)
300int n;
301register char *s;
302{
303double atof();
304char v[100];
305register char *t;
306if(n > 90)
307 {
308 err("too many digits in floating constant");
309 n = 90;
310 }
311for(t = v ; n-- > 0 ; s++)
312 *t++ = (*s=='d' ? 'e' : *s);
313*t = '\0';
314return( atof(v) );
315}
316
317
318
319Namep mkname(l, s)
320int l;
321register char *s;
322{
323struct Hashentry *hp;
324int hash;
325register Namep q;
326register int i;
327char n[VL];
328
329hash = 0;
330for(i = 0 ; i<l && *s!='\0' ; ++i)
331 {
332 hash += *s;
333 n[i] = *s++;
334 }
335hash %= maxhash;
336while( i < VL )
337 n[i++] = ' ';
338
339hp = hashtab + hash;
340while(q = hp->varp)
341 if( hash==hp->hashval && eqn(VL,n,q->varname) )
342 return(q);
343 else if(++hp >= lasthash)
344 hp = hashtab;
345
346if(++nintnames >= maxhash-1)
347 many("names", 'n');
348hp->varp = q = ALLOC(Nameblock);
349hp->hashval = hash;
350q->tag = TNAME;
351cpn(VL, n, q->varname);
352return(q);
353}
354
355
356
357struct Labelblock *mklabel(l)
358ftnint l;
359{
360register struct Labelblock *lp;
361
362if(l <= 0 || l > 99999 ) {
363 errstr("illegal label %d", l);
1792af96 364 l = 0;
be58de96
KM
365 }
366
367for(lp = labeltab ; lp < highlabtab ; ++lp)
368 if(lp->stateno == l)
369 return(lp);
370
371if(++highlabtab > labtabend)
372 many("statement numbers", 's');
373
374lp->stateno = l;
375lp->labelno = newlabel();
376lp->blklevel = 0;
377lp->labused = NO;
378lp->labdefined = NO;
379lp->labinacc = NO;
380lp->labtype = LABUNKNOWN;
381return(lp);
382}
383
384
385newlabel()
386{
387return( ++lastlabno );
388}
389
390
391/* this label appears in a branch context */
392
393struct Labelblock *execlab(stateno)
394ftnint stateno;
395{
396register struct Labelblock *lp;
397
398if(lp = mklabel(stateno))
399 {
400 if(lp->labinacc)
401 warn1("illegal branch to inner block, statement %s",
402 convic(stateno) );
403 else if(lp->labdefined == NO)
404 lp->blklevel = blklevel;
405 lp->labused = YES;
406 if(lp->labtype == LABFORMAT)
407 err("may not branch to a format");
408 else
409 lp->labtype = LABEXEC;
410 }
411
412return(lp);
413}
414
415
416
417
418
419/* find or put a name in the external symbol table */
420
421struct Extsym *mkext(s)
422char *s;
423{
424int i;
425register char *t;
426char n[XL];
427struct Extsym *p;
428
429i = 0;
430t = n;
431while(i<XL && *s)
432 *t++ = *s++;
433while(t < n+XL)
434 *t++ = ' ';
435
436for(p = extsymtab ; p<nextext ; ++p)
437 if(eqn(XL, n, p->extname))
438 return( p );
439
440if(nextext >= lastext)
441 many("external symbols", 'x');
442
443cpn(XL, n, nextext->extname);
444nextext->extstg = STGUNKNOWN;
445nextext->extsave = NO;
446nextext->extp = 0;
447nextext->extleng = 0;
448nextext->maxleng = 0;
449nextext->extinit = NO;
450return( nextext++ );
451}
452
453
454
455
456
457
458
459
460Addrp builtin(t, s)
461int t;
462char *s;
463{
464register struct Extsym *p;
465register Addrp q;
466
467p = mkext(s);
468if(p->extstg == STGUNKNOWN)
469 p->extstg = STGEXT;
470else if(p->extstg != STGEXT)
471 {
472 errstr("improper use of builtin %s", s);
473 return(0);
474 }
475
476q = ALLOC(Addrblock);
477q->tag = TADDR;
478q->vtype = t;
479q->vclass = CLPROC;
480q->vstg = STGEXT;
481q->memno = p - extsymtab;
482return(q);
483}
484
485
486
487frchain(p)
488register chainp *p;
489{
490register chainp q;
491
492if(p==0 || *p==0)
493 return;
494
495for(q = *p; q->nextp ; q = q->nextp)
496 ;
497q->nextp = chains;
498chains = *p;
499*p = 0;
500}
501
502
503tagptr cpblock(n,p)
504register int n;
505register char * p;
506{
507register char *q;
508ptr q0;
509
510q0 = ckalloc(n);
511q = (char *) q0;
512while(n-- > 0)
513 *q++ = *p++;
514return( (tagptr) q0);
515}
516
517
518
519max(a,b)
520int a,b;
521{
522return( a>b ? a : b);
523}
524
525
526ftnint lmax(a, b)
527ftnint a, b;
528{
529return( a>b ? a : b);
530}
531
532ftnint lmin(a, b)
533ftnint a, b;
534{
535return(a < b ? a : b);
536}
537
538
539
540
541maxtype(t1, t2)
542int t1, t2;
543{
544int t;
545
546t = max(t1, t2);
547if(t==TYCOMPLEX && (t1==TYDREAL || t2==TYDREAL) )
548 t = TYDCOMPLEX;
549return(t);
550}
551
552
553
554/* return log base 2 of n if n a power of 2; otherwise -1 */
555#if FAMILY == PCC
556log2(n)
557ftnint n;
558{
559int k;
560
561/* trick based on binary representation */
562
563if(n<=0 || (n & (n-1))!=0)
564 return(-1);
565
566for(k = 0 ; n >>= 1 ; ++k)
567 ;
568return(k);
569}
570#endif
571
572
573
574frrpl()
575{
576struct Rplblock *rp;
577
578while(rpllist)
579 {
580 rp = rpllist->rplnextp;
581 free( (charptr) rpllist);
582 rpllist = rp;
583 }
584}
585
586
587
588expptr callk(type, name, args)
589int type;
590char *name;
591chainp args;
592{
593register expptr p;
594
595p = mkexpr(OPCALL, builtin(type,name), args);
596p->exprblock.vtype = type;
597return(p);
598}
599
600
601
602expptr call4(type, name, arg1, arg2, arg3, arg4)
603int type;
604char *name;
605expptr arg1, arg2, arg3, arg4;
606{
607struct Listblock *args;
608args = mklist( mkchain(arg1, mkchain(arg2, mkchain(arg3,
609 mkchain(arg4, CHNULL)) ) ) );
610return( callk(type, name, args) );
611}
612
613
614
615
616expptr call3(type, name, arg1, arg2, arg3)
617int type;
618char *name;
619expptr arg1, arg2, arg3;
620{
621struct Listblock *args;
622args = mklist( mkchain(arg1, mkchain(arg2, mkchain(arg3, CHNULL) ) ) );
623return( callk(type, name, args) );
624}
625
626
627
628
629
630expptr call2(type, name, arg1, arg2)
631int type;
632char *name;
633expptr arg1, arg2;
634{
635struct Listblock *args;
636
637args = mklist( mkchain(arg1, mkchain(arg2, CHNULL) ) );
638return( callk(type,name, args) );
639}
640
641
642
643
644expptr call1(type, name, arg)
645int type;
646char *name;
647expptr arg;
648{
649return( callk(type,name, mklist(mkchain(arg,CHNULL)) ));
650}
651
652
653expptr call0(type, name)
654int type;
655char *name;
656{
657return( callk(type, name, PNULL) );
658}
659
660
661
662struct Impldoblock *mkiodo(dospec, list)
663chainp dospec, list;
664{
665register struct Impldoblock *q;
666
667q = ALLOC(Impldoblock);
668q->tag = TIMPLDO;
669q->impdospec = dospec;
670q->datalist = list;
671return(q);
672}
673
674
675
676
677ptr ckalloc(n)
678register int n;
679{
680register ptr p;
681ptr calloc();
682
683if( p = calloc(1, (unsigned) n) )
684 return(p);
685
686fatal("out of memory");
687/* NOTREACHED */
688}
689
690
691
692
693
694isaddr(p)
695register expptr p;
696{
697if(p->tag == TADDR)
698 return(YES);
699if(p->tag == TEXPR)
700 switch(p->exprblock.opcode)
701 {
702 case OPCOMMA:
703 return( isaddr(p->exprblock.rightp) );
704
705 case OPASSIGN:
706 case OPPLUSEQ:
707 return( isaddr(p->exprblock.leftp) );
708 }
709return(NO);
710}
711
712
713
714
715isstatic(p)
716register expptr p;
717{
718if(p->headblock.vleng && !ISCONST(p->headblock.vleng))
719 return(NO);
720
721switch(p->tag)
722 {
723 case TCONST:
724 return(YES);
725
726 case TADDR:
727 if(ONEOF(p->addrblock.vstg,MSKSTATIC) &&
728 ISCONST(p->addrblock.memoffset))
729 return(YES);
730
731 default:
732 return(NO);
733 }
734}
735
736
737
738addressable(p)
739register expptr p;
740{
741switch(p->tag)
742 {
743 case TCONST:
744 return(YES);
745
746 case TADDR:
747 return( addressable(p->addrblock.memoffset) );
748
749 default:
750 return(NO);
751 }
752}
753
754
755
756hextoi(c)
757register int c;
758{
759register char *p;
760static char p0[17] = "0123456789abcdef";
761
762for(p = p0 ; *p ; ++p)
763 if(*p == c)
764 return( p-p0 );
765return(16);
766}