xref: /original-bsd/usr.bin/f77/pass1.vax/misc.c (revision b9d18e58)
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
8 static char sccsid[] = "@(#)misc.c	5.2 (Berkeley) 01/07/86";
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 $
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  *
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 
34 cpn(n, a, b)
35 register int n;
36 register char *a, *b;
37 {
38 while(--n >= 0)
39 	*b++ = *a++;
40 }
41 
42 
43 
44 eqn(n, a, b)
45 register int n;
46 register char *a, *b;
47 {
48 while(--n >= 0)
49 	if(*a++ != *b++)
50 		return(NO);
51 return(YES);
52 }
53 
54 
55 
56 
57 
58 
59 
60 cmpstr(a, b, la, lb)	/* compare two strings */
61 register char *a, *b;
62 ftnint la, lb;
63 {
64 register char *aend, *bend;
65 aend = a + la;
66 bend = b + lb;
67 
68 
69 if(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 
84 else
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 	}
97 return(0);
98 }
99 
100 
101 
102 
103 
104 chainp hookup(x,y)
105 register chainp x, y;
106 {
107 register chainp p;
108 
109 if(x == NULL)
110 	return(y);
111 
112 for(p = x ; p->nextp ; p = p->nextp)
113 	;
114 p->nextp = y;
115 return(x);
116 }
117 
118 
119 
120 struct Listblock *mklist(p)
121 chainp p;
122 {
123 register struct Listblock *q;
124 
125 q = ALLOC(Listblock);
126 q->tag = TLIST;
127 q->listp = p;
128 return(q);
129 }
130 
131 
132 chainp mkchain(p,q)
133 register tagptr p;
134 register chainp q;
135 {
136 register chainp r;
137 
138 if(chains)
139 	{
140 	r = chains;
141 	chains = chains->nextp;
142 	}
143 else
144 	r = ALLOC(Chain);
145 
146 r->datap = p;
147 r->nextp = q;
148 return(r);
149 }
150 
151 
152 
153 char * varstr(n, s)
154 register int n;
155 register char *s;
156 {
157 register int i;
158 static char name[XL+1];
159 
160 for(i=0;  i<n && *s!=' ' && *s!='\0' ; ++i)
161 	name[i] = *s++;
162 
163 name[i] = '\0';
164 
165 return( name );
166 }
167 
168 
169 
170 
171 char * varunder(n, s)
172 register int n;
173 register char *s;
174 {
175 register int i;
176 static char name[XL+1];
177 
178 for(i=0;  i<n && *s!=' ' && *s!='\0' ; ++i)
179 	name[i] = *s++;
180 
181 #if TARGET != GCOS
182 name[i++] = '_';
183 #endif
184 
185 name[i] = '\0';
186 
187 return( name );
188 }
189 
190 
191 
192 
193 
194 char * nounder(n, s)
195 register int n;
196 register char *s;
197 {
198 register int i;
199 static char name[XL+1];
200 
201 for(i=0;  i<n && *s!=' ' && *s!='\0' ; ++s)
202 	if(*s != '_')
203 		name[i++] = *s;
204 
205 name[i] = '\0';
206 
207 return( name );
208 }
209 
210 
211 
212 char *copyn(n, s)
213 register int n;
214 register char *s;
215 {
216 register char *p, *q;
217 
218 p = q = (char *) ckalloc(n);
219 while(--n >= 0)
220 	*q++ = *s++;
221 return(p);
222 }
223 
224 
225 
226 char *copys(s)
227 char *s;
228 {
229 return( copyn( strlen(s)+1 , s) );
230 }
231 
232 
233 
234 ftnint convci(n, s)
235 register int n;
236 register char *s;
237 {
238 ftnint sum;
239 ftnint digval;
240 sum = 0;
241 while(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 	}
277 return(sum);
278 }
279 
280 char *convic(n)
281 ftnint n;
282 {
283 static char s[20];
284 register char *t;
285 
286 s[19] = '\0';
287 t = s+19;
288 
289 do	{
290 	*--t = '0' + n%10;
291 	n /= 10;
292 	} while(n > 0);
293 
294 return(t);
295 }
296 
297 
298 
299 double convcd(n, s)
300 int n;
301 register char *s;
302 {
303 double atof();
304 char v[100];
305 register char *t;
306 if(n > 90)
307 	{
308 	err("too many digits in floating constant");
309 	n = 90;
310 	}
311 for(t = v ; n-- > 0 ; s++)
312 	*t++ = (*s=='d' ? 'e' : *s);
313 *t = '\0';
314 return( atof(v) );
315 }
316 
317 
318 
319 Namep mkname(l, s)
320 int l;
321 register char *s;
322 {
323 struct Hashentry *hp;
324 int hash;
325 register Namep q;
326 register int i;
327 char n[VL];
328 
329 hash = 0;
330 for(i = 0 ; i<l && *s!='\0' ; ++i)
331 	{
332 	hash += *s;
333 	n[i] = *s++;
334 	}
335 hash %= maxhash;
336 while( i < VL )
337 	n[i++] = ' ';
338 
339 hp = hashtab + hash;
340 while(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 
346 if(++nintnames >= maxhash-1)
347 	many("names", 'n');
348 hp->varp = q = ALLOC(Nameblock);
349 hp->hashval = hash;
350 q->tag = TNAME;
351 cpn(VL, n, q->varname);
352 return(q);
353 }
354 
355 
356 
357 struct Labelblock *mklabel(l)
358 ftnint l;
359 {
360 register struct Labelblock *lp;
361 
362 if(l <= 0 || l > 99999 ) {
363 	errstr("illegal label %d", l);
364 	l = 0;
365 	}
366 
367 for(lp = labeltab ; lp < highlabtab ; ++lp)
368 	if(lp->stateno == l)
369 		return(lp);
370 
371 if(++highlabtab > labtabend)
372 	many("statement numbers", 's');
373 
374 lp->stateno = l;
375 lp->labelno = newlabel();
376 lp->blklevel = 0;
377 lp->labused = NO;
378 lp->labdefined = NO;
379 lp->labinacc = NO;
380 lp->labtype = LABUNKNOWN;
381 return(lp);
382 }
383 
384 
385 newlabel()
386 {
387 return( ++lastlabno );
388 }
389 
390 
391 /* this label appears in a branch context */
392 
393 struct Labelblock *execlab(stateno)
394 ftnint stateno;
395 {
396 register struct Labelblock *lp;
397 
398 if(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 
412 return(lp);
413 }
414 
415 
416 
417 
418 
419 /* find or put a name in the external symbol table */
420 
421 struct Extsym *mkext(s)
422 char *s;
423 {
424 int i;
425 register char *t;
426 char n[XL];
427 struct Extsym *p;
428 
429 i = 0;
430 t = n;
431 while(i<XL && *s)
432 	*t++ = *s++;
433 while(t < n+XL)
434 	*t++ = ' ';
435 
436 for(p = extsymtab ; p<nextext ; ++p)
437 	if(eqn(XL, n, p->extname))
438 		return( p );
439 
440 if(nextext >= lastext)
441 	many("external symbols", 'x');
442 
443 cpn(XL, n, nextext->extname);
444 nextext->extstg = STGUNKNOWN;
445 nextext->extsave = NO;
446 nextext->extp = 0;
447 nextext->extleng = 0;
448 nextext->maxleng = 0;
449 nextext->extinit = NO;
450 return( nextext++ );
451 }
452 
453 
454 
455 
456 
457 
458 
459 
460 Addrp builtin(t, s)
461 int t;
462 char *s;
463 {
464 register struct Extsym *p;
465 register Addrp q;
466 
467 p = mkext(s);
468 if(p->extstg == STGUNKNOWN)
469 	p->extstg = STGEXT;
470 else if(p->extstg != STGEXT)
471 	{
472 	errstr("improper use of builtin %s", s);
473 	return(0);
474 	}
475 
476 q = ALLOC(Addrblock);
477 q->tag = TADDR;
478 q->vtype = t;
479 q->vclass = CLPROC;
480 q->vstg = STGEXT;
481 q->memno = p - extsymtab;
482 return(q);
483 }
484 
485 
486 
487 frchain(p)
488 register chainp *p;
489 {
490 register chainp q;
491 
492 if(p==0 || *p==0)
493 	return;
494 
495 for(q = *p; q->nextp ; q = q->nextp)
496 	;
497 q->nextp = chains;
498 chains = *p;
499 *p = 0;
500 }
501 
502 
503 tagptr cpblock(n,p)
504 register int n;
505 register char * p;
506 {
507 register char *q;
508 ptr q0;
509 
510 q0 = ckalloc(n);
511 q = (char *) q0;
512 while(n-- > 0)
513 	*q++ = *p++;
514 return( (tagptr) q0);
515 }
516 
517 
518 
519 max(a,b)
520 int a,b;
521 {
522 return( a>b ? a : b);
523 }
524 
525 
526 ftnint lmax(a, b)
527 ftnint a, b;
528 {
529 return( a>b ? a : b);
530 }
531 
532 ftnint lmin(a, b)
533 ftnint a, b;
534 {
535 return(a < b ? a : b);
536 }
537 
538 
539 
540 
541 maxtype(t1, t2)
542 int t1, t2;
543 {
544 int t;
545 
546 t = max(t1, t2);
547 if(t==TYCOMPLEX && (t1==TYDREAL || t2==TYDREAL) )
548 	t = TYDCOMPLEX;
549 return(t);
550 }
551 
552 
553 
554 /* return log base 2 of n if n a power of 2; otherwise -1 */
555 #if FAMILY == PCC
556 log2(n)
557 ftnint n;
558 {
559 int k;
560 
561 /* trick based on binary representation */
562 
563 if(n<=0 || (n & (n-1))!=0)
564 	return(-1);
565 
566 for(k = 0 ;  n >>= 1  ; ++k)
567 	;
568 return(k);
569 }
570 #endif
571 
572 
573 
574 frrpl()
575 {
576 struct Rplblock *rp;
577 
578 while(rpllist)
579 	{
580 	rp = rpllist->rplnextp;
581 	free( (charptr) rpllist);
582 	rpllist = rp;
583 	}
584 }
585 
586 
587 
588 expptr callk(type, name, args)
589 int type;
590 char *name;
591 chainp args;
592 {
593 register expptr p;
594 
595 p = mkexpr(OPCALL, builtin(type,name), args);
596 p->exprblock.vtype = type;
597 return(p);
598 }
599 
600 
601 
602 expptr call4(type, name, arg1, arg2, arg3, arg4)
603 int type;
604 char *name;
605 expptr arg1, arg2, arg3, arg4;
606 {
607 struct Listblock *args;
608 args = mklist( mkchain(arg1, mkchain(arg2, mkchain(arg3,
609 	mkchain(arg4, CHNULL)) ) ) );
610 return( callk(type, name, args) );
611 }
612 
613 
614 
615 
616 expptr call3(type, name, arg1, arg2, arg3)
617 int type;
618 char *name;
619 expptr arg1, arg2, arg3;
620 {
621 struct Listblock *args;
622 args = mklist( mkchain(arg1, mkchain(arg2, mkchain(arg3, CHNULL) ) ) );
623 return( callk(type, name, args) );
624 }
625 
626 
627 
628 
629 
630 expptr call2(type, name, arg1, arg2)
631 int type;
632 char *name;
633 expptr arg1, arg2;
634 {
635 struct Listblock *args;
636 
637 args = mklist( mkchain(arg1, mkchain(arg2, CHNULL) ) );
638 return( callk(type,name, args) );
639 }
640 
641 
642 
643 
644 expptr call1(type, name, arg)
645 int type;
646 char *name;
647 expptr arg;
648 {
649 return( callk(type,name, mklist(mkchain(arg,CHNULL)) ));
650 }
651 
652 
653 expptr call0(type, name)
654 int type;
655 char *name;
656 {
657 return( callk(type, name, PNULL) );
658 }
659 
660 
661 
662 struct Impldoblock *mkiodo(dospec, list)
663 chainp dospec, list;
664 {
665 register struct Impldoblock *q;
666 
667 q = ALLOC(Impldoblock);
668 q->tag = TIMPLDO;
669 q->impdospec = dospec;
670 q->datalist = list;
671 return(q);
672 }
673 
674 
675 
676 
677 ptr ckalloc(n)
678 register int n;
679 {
680 register ptr p;
681 ptr calloc();
682 
683 if( p = calloc(1, (unsigned) n) )
684 	return(p);
685 
686 fatal("out of memory");
687 /* NOTREACHED */
688 }
689 
690 
691 
692 
693 
694 isaddr(p)
695 register expptr p;
696 {
697 if(p->tag == TADDR)
698 	return(YES);
699 if(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 		}
709 return(NO);
710 }
711 
712 
713 
714 
715 isstatic(p)
716 register expptr p;
717 {
718 if(p->headblock.vleng && !ISCONST(p->headblock.vleng))
719 	return(NO);
720 
721 switch(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 
738 addressable(p)
739 register expptr p;
740 {
741 switch(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 
756 hextoi(c)
757 register int c;
758 {
759 register char *p;
760 static char p0[17] = "0123456789abcdef";
761 
762 for(p = p0 ; *p ; ++p)
763 	if(*p == c)
764 		return( p-p0 );
765 return(16);
766 }
767