* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
static char sccsid
[] = "@(#)misc.c 5.2 (Berkeley) 1/7/86";
* Miscellaneous routines for the f77 compiler, 4.2 BSD.
* University of Utah CS Dept modification history:
* Revision 5.2 85/12/18 00:35:08 donn
* Prevent core dumps for peculiar statement numbers.
* Revision 5.1 85/08/10 03:48:29 donn
* Revision 3.1 84/10/13 01:53:26 donn
* Installed Jerry Berkman's version; added UofU comment header.
cmpstr(a
, b
, la
, lb
) /* compare two strings */
register char *aend
, *bend
;
for(p
= x
; p
->nextp
; p
= p
->nextp
)
struct Listblock
*mklist(p
)
register struct Listblock
*q
;
for(i
=0; i
<n
&& *s
!=' ' && *s
!='\0' ; ++i
)
for(i
=0; i
<n
&& *s
!=' ' && *s
!='\0' ; ++i
)
for(i
=0; i
<n
&& *s
!=' ' && *s
!='\0' ; ++s
)
p
= q
= (char *) ckalloc(n
);
return( copyn( strlen(s
)+1 , s
) );
err("integer constant too large");
if ( MAXINT
- sum
>= digval
) {
/* KLUDGE. On VAXs, MININT is (-MAXINT)-1 , i.e., there
is one more neg. integer than pos. integer. The
following code returns MININT whenever (MAXINT+1)
is seen. On VAXs, such statements as: i = MININT
work, although this generates garbage for
such statements as: i = MPLUS1 where MPLUS1 is MAXINT+1
or: i = 5 - 2147483647/2 .
The only excuse for this kludge is it keeps all legal
programs running and flags most illegal constants, unlike
the previous version which flaged nothing outside data stmts!
if ( n
== 0 && MAXINT
- sum
+ 1 == digval
) {
warn("minimum negative integer compiled - possibly bad code");
err("integer constant too large");
err("too many digits in floating constant");
for(t
= v
; n
-- > 0 ; s
++)
*t
++ = (*s
=='d' ? 'e' : *s
);
for(i
= 0 ; i
<l
&& *s
!='\0' ; ++i
)
if( hash
==hp
->hashval
&& eqn(VL
,n
,q
->varname
) )
else if(++hp
>= lasthash
)
if(++nintnames
>= maxhash
-1)
hp
->varp
= q
= ALLOC(Nameblock
);
struct Labelblock
*mklabel(l
)
register struct Labelblock
*lp
;
if(l
<= 0 || l
> 99999 ) {
errstr("illegal label %d", l
);
for(lp
= labeltab
; lp
< highlabtab
; ++lp
)
if(++highlabtab
> labtabend
)
many("statement numbers", 's');
lp
->labelno
= newlabel();
lp
->labtype
= LABUNKNOWN
;
/* this label appears in a branch context */
struct Labelblock
*execlab(stateno
)
register struct Labelblock
*lp
;
if(lp
= mklabel(stateno
))
warn1("illegal branch to inner block, statement %s",
else if(lp
->labdefined
== NO
)
if(lp
->labtype
== LABFORMAT
)
err("may not branch to a format");
/* find or put a name in the external symbol table */
for(p
= extsymtab
; p
<nextext
; ++p
)
if(eqn(XL
, n
, p
->extname
))
many("external symbols", 'x');
cpn(XL
, n
, nextext
->extname
);
nextext
->extstg
= STGUNKNOWN
;
register struct Extsym
*p
;
if(p
->extstg
== STGUNKNOWN
)
else if(p
->extstg
!= STGEXT
)
errstr("improper use of builtin %s", s
);
q
->memno
= p
- extsymtab
;
for(q
= *p
; q
->nextp
; q
= q
->nextp
)
if(t
==TYCOMPLEX
&& (t1
==TYDREAL
|| t2
==TYDREAL
) )
/* return log base 2 of n if n a power of 2; otherwise -1 */
/* trick based on binary representation */
if(n
<=0 || (n
& (n
-1))!=0)
for(k
= 0 ; n
>>= 1 ; ++k
)
free( (charptr
) rpllist
);
expptr
callk(type
, name
, args
)
p
= mkexpr(OPCALL
, builtin(type
,name
), args
);
p
->exprblock
.vtype
= type
;
expptr
call4(type
, name
, arg1
, arg2
, arg3
, arg4
)
expptr arg1
, arg2
, arg3
, arg4
;
args
= mklist( mkchain(arg1
, mkchain(arg2
, mkchain(arg3
,
mkchain(arg4
, CHNULL
)) ) ) );
return( callk(type
, name
, args
) );
expptr
call3(type
, name
, arg1
, arg2
, arg3
)
args
= mklist( mkchain(arg1
, mkchain(arg2
, mkchain(arg3
, CHNULL
) ) ) );
return( callk(type
, name
, args
) );
expptr
call2(type
, name
, arg1
, arg2
)
args
= mklist( mkchain(arg1
, mkchain(arg2
, CHNULL
) ) );
return( callk(type
,name
, args
) );
expptr
call1(type
, name
, arg
)
return( callk(type
,name
, mklist(mkchain(arg
,CHNULL
)) ));
return( callk(type
, name
, PNULL
) );
struct Impldoblock
*mkiodo(dospec
, list
)
register struct Impldoblock
*q
;
if( p
= calloc(1, (unsigned) n
) )
switch(p
->exprblock
.opcode
)
return( isaddr(p
->exprblock
.rightp
) );
return( isaddr(p
->exprblock
.leftp
) );
if(p
->headblock
.vleng
&& !ISCONST(p
->headblock
.vleng
))
if(ONEOF(p
->addrblock
.vstg
,MSKSTATIC
) &&
ISCONST(p
->addrblock
.memoffset
))
return( addressable(p
->addrblock
.memoffset
) );
static char p0
[17] = "0123456789abcdef";