xref: /netbsd/external/bsd/pcc/dist/pcc/f77/fcom/misc.c (revision 3eb51a41)
1 /*	Id: misc.c,v 1.17 2009/02/11 15:58:55 ragge Exp 	*/
2 /*	$NetBSD: misc.c,v 1.1.1.3 2010/06/03 18:57:50 plunky Exp $	*/
3 /*
4  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * Redistributions of source code and documentation must retain the above
11  * copyright notice, this list of conditions and the following disclaimer.
12  * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  * All advertising materials mentioning features or use of this software
16  * must display the following acknowledgement:
17  * 	This product includes software developed or owned by Caldera
18  *	International, Inc.
19  * Neither the name of Caldera International, Inc. nor the names of other
20  * contributors may be used to endorse or promote products derived from
21  * this software without specific prior written permission.
22  *
23  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
24  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
28  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
32  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
33  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  */
36 
37 #include <string.h>
38 
39 #include "defines.h"
40 #include "defs.h"
41 
42 int max(int, int);
43 
44 void
cpn(n,a,b)45 cpn(n, a, b)
46 register int n;
47 register char *a, *b;
48 {
49 while(--n >= 0)
50 	*b++ = *a++;
51 }
52 
53 
54 int
eqn(n,a,b)55 eqn(n, a, b)
56 register int n;
57 register char *a, *b;
58 {
59 while(--n >= 0)
60 	if(*a++ != *b++)
61 		return(NO);
62 return(YES);
63 }
64 
65 
66 
67 
68 
69 
70 int
cmpstr(a,b,la,lb)71 cmpstr(a, b, la, lb)	/* compare two strings */
72 register char *a, *b;
73 ftnint la, lb;
74 {
75 register char *aend, *bend;
76 aend = a + la;
77 bend = b + lb;
78 
79 
80 if(la <= lb)
81 	{
82 	while(a < aend)
83 		if(*a != *b)
84 			return( *a - *b );
85 		else
86 			{ ++a; ++b; }
87 
88 	while(b < bend)
89 		if(*b != ' ')
90 			return(' ' - *b);
91 		else
92 			++b;
93 	}
94 
95 else
96 	{
97 	while(b < bend)
98 		if(*a != *b)
99 			return( *a - *b );
100 		else
101 			{ ++a; ++b; }
102 	while(a < aend)
103 		if(*a != ' ')
104 			return(*a - ' ');
105 		else
106 			++a;
107 	}
108 return(0);
109 }
110 
111 
112 
113 
114 
hookup(x,y)115 chainp hookup(x,y)
116 register chainp x, y;
117 {
118 register chainp p;
119 
120 if(x == NULL)
121 	return(y);
122 
123 for(p = x ; p->chain.nextp ; p = p->chain.nextp)
124 	;
125 p->chain.nextp = y;
126 return(x);
127 }
128 
129 
130 
mklist(p)131 struct bigblock *mklist(p)
132 chainp p;
133 {
134 register struct bigblock *q;
135 
136 q = BALLO();
137 q->tag = TLIST;
138 q->b_list.listp = p;
139 return(q);
140 }
141 
142 
143 chainp
mkchain(bigptr p,chainp q)144 mkchain(bigptr p, chainp q)
145 {
146 	chainp r;
147 
148 	if(chains) {
149 		r = chains;
150 		chains = chains->chain.nextp;
151 	} else
152 		r = ALLOC(chain);
153 
154 	r->chain.datap = p;
155 	r->chain.nextp = q;
156 	return(r);
157 }
158 
159 
160 
varstr(n,s)161 char * varstr(n, s)
162 register int n;
163 register char *s;
164 {
165 register int i;
166 static char name[XL+1];
167 
168 for(i=0;  i<n && *s!=' ' && *s!='\0' ; ++i)
169 	name[i] = *s++;
170 
171 name[i] = '\0';
172 
173 return( name );
174 }
175 
176 
177 
178 
varunder(n,s)179 char * varunder(n, s)
180 register int n;
181 register char *s;
182 {
183 register int i;
184 static char name[XL+1];
185 
186 for(i=0;  i<n && *s!=' ' && *s!='\0' ; ++i)
187 	name[i] = *s++;
188 
189 name[i] = '\0';
190 
191 return( name );
192 }
193 
194 
195 
196 
197 
nounder(n,s)198 char * nounder(n, s)
199 register int n;
200 register char *s;
201 {
202 register int i;
203 static char name[XL+1];
204 
205 for(i=0;  i<n && *s!=' ' && *s!='\0' ; ++s)
206 	if(*s != '_')
207 		name[i++] = *s;
208 
209 name[i] = '\0';
210 
211 return( name );
212 }
213 
214 /*
215  * Save a block on heap.
216  */
217 char *
copyn(int n,char * s)218 copyn(int n, char *s)
219 {
220 	char *p, *q;
221 
222 	p = q = ckalloc(n);
223 	while(--n >= 0)
224 		*q++ = *s++;
225 	return(p);
226 }
227 
228 /*
229  * Save a string on heap.
230  */
231 char *
copys(char * s)232 copys(char *s)
233 {
234 	return(copyn(strlen(s)+1 , s));
235 }
236 
237 /*
238  * convert a string to an int.
239  */
240 ftnint
convci(int n,char * s)241 convci(int n, char *s)
242 {
243 	ftnint sum;
244 	sum = 0;
245 	while(n-- > 0)
246 		sum = 10*sum + (*s++ - '0');
247 	return(sum);
248 }
249 
convic(n)250 char *convic(n)
251 ftnint n;
252 {
253 static char s[20];
254 register char *t;
255 
256 s[19] = '\0';
257 t = s+19;
258 
259 do	{
260 	*--t = '0' + n%10;
261 	n /= 10;
262 	} while(n > 0);
263 
264 return(t);
265 }
266 
267 
268 
convcd(n,s)269 double convcd(n, s)
270 int n;
271 register char *s;
272 {
273 char v[100];
274 register char *t;
275 if(n > 90)
276 	{
277 	err("too many digits in floating constant");
278 	n = 90;
279 	}
280 for(t = v ; n-- > 0 ; s++)
281 	*t++ = (*s=='d' ? 'e' : *s);
282 *t = '\0';
283 return( atof(v) );
284 }
285 
286 
287 
mkname(l,s)288 struct bigblock *mkname(l, s)
289 int l;
290 register char *s;
291 {
292 struct hashentry *hp;
293 int hash;
294 register struct bigblock *q;
295 register int i;
296 char n[VL];
297 
298 hash = 0;
299 for(i = 0 ; i<l && *s!='\0' ; ++i)
300 	{
301 	hash += *s;
302 	n[i] = *s++;
303 	}
304 hash %= MAXHASH;
305 while( i < VL )
306 	n[i++] = ' ';
307 
308 hp = hashtab + hash;
309 while((q = hp->varp))
310 	if( hash==hp->hashval && eqn(VL,n,q->b_name.varname) )
311 		return(q);
312 	else if(++hp >= lasthash)
313 		hp = hashtab;
314 
315 if(++nintnames >= MAXHASH-1)
316 	fatal("hash table full");
317 hp->varp = q = BALLO();
318 hp->hashval = hash;
319 q->tag = TNAME;
320 cpn(VL, n, q->b_name.varname);
321 return(q);
322 }
323 
324 
325 
mklabel(l)326 struct labelblock *mklabel(l)
327 ftnint l;
328 {
329 register struct labelblock *lp;
330 
331 if(l == 0)
332 	return(0);
333 
334 for(lp = labeltab ; lp < highlabtab ; ++lp)
335 	if(lp->stateno == l)
336 		return(lp);
337 
338 if(++highlabtab >= labtabend)
339 	fatal("too many statement numbers");
340 
341 lp->stateno = l;
342 lp->labelno = newlabel();
343 lp->blklevel = 0;
344 lp->labused = NO;
345 lp->labdefined = NO;
346 lp->labinacc = NO;
347 lp->labtype = LABUNKNOWN;
348 return(lp);
349 }
350 
351 int
newlabel()352 newlabel()
353 {
354 return( lastlabno++ );
355 }
356 
357 
358 /* find or put a name in the external symbol table */
359 
mkext(s)360 struct extsym *mkext(s)
361 char *s;
362 {
363 int i;
364 register char *t;
365 char n[XL];
366 struct extsym *p;
367 
368 i = 0;
369 t = n;
370 while(i<XL && *s)
371 	*t++ = *s++;
372 while(t < n+XL)
373 	*t++ = ' ';
374 
375 for(p = extsymtab ; p<nextext ; ++p)
376 	if(eqn(XL, n, p->extname))
377 		return( p );
378 
379 if(nextext >= lastext)
380 	fatal("too many external symbols");
381 
382 cpn(XL, n, nextext->extname);
383 nextext->extstg = STGUNKNOWN;
384 nextext->extsave = NO;
385 nextext->extp = 0;
386 nextext->extleng = 0;
387 nextext->maxleng = 0;
388 nextext->extinit = NO;
389 return( nextext++ );
390 }
391 
392 
393 
394 
395 
396 
397 
398 
builtin(t,s)399 struct bigblock *builtin(t, s)
400 int t;
401 char *s;
402 {
403 register struct extsym *p;
404 register struct bigblock *q;
405 
406 p = mkext(s);
407 if(p->extstg == STGUNKNOWN)
408 	p->extstg = STGEXT;
409 else if(p->extstg != STGEXT)
410 	{
411 	err1("improper use of builtin %s", s);
412 	return(0);
413 	}
414 
415 q = BALLO();
416 q->tag = TADDR;
417 q->vtype = t;
418 q->vclass = CLPROC;
419 q->vstg = STGEXT;
420 q->b_addr.memno = p - extsymtab;
421 return(q);
422 }
423 
424 
425 void
frchain(p)426 frchain(p)
427 register chainp *p;
428 {
429 register chainp q;
430 
431 if(p==0 || *p==0)
432 	return;
433 
434 for(q = *p; q->chain.nextp ; q = q->chain.nextp)
435 	;
436 q->chain.nextp = chains;
437 chains = *p;
438 *p = 0;
439 }
440 
441 
cpblock(n,p)442 ptr cpblock(n,p)
443 register int n;
444 register void * p;
445 {
446 register char *q, *r = p;
447 ptr q0;
448 
449 q = q0 = ckalloc(n);
450 while(n-- > 0)
451 	*q++ = *r++;
452 return(q0);
453 }
454 
455 
456 int
max(a,b)457 max(a,b)
458 int a,b;
459 {
460 return( a>b ? a : b);
461 }
462 
463 
lmax(a,b)464 ftnint lmax(a, b)
465 ftnint a, b;
466 {
467 return( a>b ? a : b);
468 }
469 
lmin(a,b)470 ftnint lmin(a, b)
471 ftnint a, b;
472 {
473 return(a < b ? a : b);
474 }
475 
476 
477 
478 int
maxtype(t1,t2)479 maxtype(t1, t2)
480 int t1, t2;
481 {
482 int t;
483 
484 t = max(t1, t2);
485 if(t==TYCOMPLEX && (t1==TYDREAL || t2==TYDREAL) )
486 	t = TYDCOMPLEX;
487 return(t);
488 }
489 
490 
491 
492 /* return log base 2 of n if n a power of 2; otherwise -1 */
493 int
flog2(n)494 flog2(n)
495 ftnint n;
496 {
497 int k;
498 
499 /* trick based on binary representation */
500 
501 if(n<=0 || (n & (n-1))!=0)
502 	return(-1);
503 
504 for(k = 0 ;  n >>= 1  ; ++k)
505 	;
506 return(k);
507 }
508 
509 
510 void
frrpl()511 frrpl()
512 {
513 chainp rp;
514 
515 while(rpllist)
516 	{
517 	rp = rpllist->rplblock.nextp;
518 	ckfree(rpllist);
519 	rpllist = rp;
520 	}
521 }
522 
523 void
popstack(p)524 popstack(p)
525 register chainp *p;
526 {
527 register chainp q;
528 
529 if(p==NULL || *p==NULL)
530 	fatal("popstack: stack empty");
531 q = (*p)->chain.nextp;
532 ckfree(*p);
533 *p = q;
534 }
535 
536 
537 
538 struct bigblock *
callk(type,name,args)539 callk(type, name, args)
540 int type;
541 char *name;
542 bigptr args;
543 {
544 register struct bigblock *p;
545 
546 p = mkexpr(OPCALL, builtin(type,name), args);
547 p->vtype = type;
548 return(p);
549 }
550 
551 
552 
553 struct bigblock *
call4(type,name,arg1,arg2,arg3,arg4)554 call4(type, name, arg1, arg2, arg3, arg4)
555 int type;
556 char *name;
557 bigptr arg1, arg2, arg3, arg4;
558 {
559 struct bigblock *args;
560 args = mklist( mkchain(arg1, mkchain(arg2, mkchain(arg3, mkchain(arg4, NULL)) ) ) );
561 return( callk(type, name, args) );
562 }
563 
564 
565 
566 
call3(type,name,arg1,arg2,arg3)567 struct bigblock *call3(type, name, arg1, arg2, arg3)
568 int type;
569 char *name;
570 bigptr arg1, arg2, arg3;
571 {
572 struct bigblock *args;
573 args = mklist( mkchain(arg1, mkchain(arg2, mkchain(arg3, NULL) ) ) );
574 return( callk(type, name, args) );
575 }
576 
577 
578 
579 
580 
581 struct bigblock *
call2(type,name,arg1,arg2)582 call2(type, name, arg1, arg2)
583 int type;
584 char *name;
585 bigptr arg1, arg2;
586 {
587 bigptr args;
588 
589 args = mklist( mkchain(arg1, mkchain(arg2, NULL) ) );
590 return( callk(type,name, args) );
591 }
592 
593 
594 
595 
call1(type,name,arg)596 struct bigblock *call1(type, name, arg)
597 int type;
598 char *name;
599 bigptr arg;
600 {
601 return( callk(type,name, mklist(mkchain(arg,0)) ));
602 }
603 
604 
call0(type,name)605 struct bigblock *call0(type, name)
606 int type;
607 char *name;
608 {
609 return( callk(type, name, NULL) );
610 }
611 
612 
613 
614 struct bigblock *
mkiodo(dospec,list)615 mkiodo(dospec, list)
616 chainp dospec, list;
617 {
618 register struct bigblock *q;
619 
620 q = BALLO();
621 q->tag = TIMPLDO;
622 q->b_impldo.varnp = (struct bigblock *)dospec;
623 q->b_impldo.datalist = list;
624 return(q);
625 }
626 
627 
628 
629 
630 ptr
ckalloc(int n)631 ckalloc(int n)
632 {
633 	ptr p;
634 
635 	if ((p = calloc(1, (unsigned) n)) == NULL)
636 		fatal("out of memory");
637 #ifdef PCC_DEBUG
638 	if (mflag)
639 		printf("ckalloc: sz %d ptr %p\n", n, p);
640 #endif
641 	return(p);
642 }
643 
644 void
ckfree(void * p)645 ckfree(void *p)
646 {
647 #ifdef PCC_DEBUG
648 	if (mflag)
649 		printf("ckfree: ptr %p\n", p);
650 #endif
651 	free(p);
652 }
653 
654 #if 0
655 int
656 isaddr(p)
657 register bigptr p;
658 {
659 if(p->tag == TADDR)
660 	return(YES);
661 if(p->tag == TEXPR)
662 	switch(p->b_expr.opcode)
663 		{
664 		case OPCOMMA:
665 			return( isaddr(p->b_expr.rightp) );
666 
667 		case OPASSIGN:
668 		case OPPLUSEQ:
669 			return( isaddr(p->b_expr.leftp) );
670 		}
671 return(NO);
672 }
673 #endif
674 
675 /*
676  * Return YES if not an expression.
677  */
678 int
addressable(bigptr p)679 addressable(bigptr p)
680 {
681 	switch(p->tag) {
682 	case TCONST:
683 		return(YES);
684 
685 	case TADDR:
686 		return( addressable(p->b_addr.memoffset) );
687 
688 	default:
689 		return(NO);
690 	}
691 }
692 
693 
694 int
hextoi(c)695 hextoi(c)
696 register int c;
697 {
698 register char *p;
699 static char p0[17] = "0123456789abcdef";
700 
701 for(p = p0 ; *p ; ++p)
702 	if(*p == c)
703 		return( p-p0 );
704 return(16);
705 }
706