int strftn
= 0; /* is the current function one which returns a value */
/* output a branch to label n */
/* exception is an ordinary function branching to retlab: then, return */
if( n
== retlab
&& !strftn
){
else printf( " jbr L%d\n", n
);
/* cause the alignment to become a multiple of n */
if( lastloc
!= PROG
&& n
> 1 ) printf( " .even\n" );
/* l is PROG, ADATA, DATA, STRNG, ISTRNG, or STAB */
if( l
== lastloc
) return(l
);
if( temp
!= DATA
&& temp
!= ADATA
)
cerror( "locctr: STAB unused" );
cerror( "illegal location counter" );
/* output something to define the current position as label n */
fprintf( outfile
, "L%d:\n", n
);
/* return a number usable for a label */
/* code for the end of a function */
if( strftn
){ /* copy output (in r0) to caller */
register struct symtab
*p
;
printf( " mov $L%d,r1\n", stlab
);
size
= tsize( DECREF(p
->stype
), p
->dimoff
, p
->sizoff
) / SZCHAR
;
printf( " mov (r0)+,(r1)+\n" );
printf( " mov $L%d,r0\n", stlab
);
printf( " .bss\nL%d: .=.+%d.\n .text\n", stlab
, size
);
/* turn off strftn flag, so return sequence will be generated */
bfcode( a
, n
) int a
[]; {
/* code for the beginning of a function; a is an array of
indices in stab for the arguments; n is the number */
register struct symtab
*p
;
strftn
= (temp
==STRTY
) || (temp
==UNIONTY
);
printf( " mov $L%d,r0\n", plab
);
printf( " jsr pc,mcount\n" );
printf( " .bss\nL%d: .=.+2\n .text\n", plab
);
printf( " jsr r5,csv\n" );
/* adjust stack for autos */
printf( " sub $.F%d,sp\n", ftnno
);
if( p
->sclass
== REGISTER
){
temp
= p
->offset
; /* save register number */
p
->sclass
= PARAM
; /* forget that it is a register */
printf( " mov %d.(r5),r%d\n", p
->offset
/SZCHAR
, temp
);
p
->offset
= temp
; /* remember register number */
p
->sclass
= REGISTER
; /* remember that it is a register */
if( oalloc( p
, &off
) ) cerror( "bad argument" );
bccode(){ /* called just before the first executable statment */
/* by now, the automatics and register variables are allocated */
SETOFF( autooff
, SZINT
);
/* set aside store area offset */
p2bbeg( autooff
, regvar
);
/* called just before final exit */
/* flag is 1 if errors, 0 if none */
/* called before removing automatics from stab */
aocode(p
) struct symtab
*p
; {
/* called when automatic p removed from stab */
/* called after removing all automatics from stab */
defnam( p
) register struct symtab
*p
; {
/* define the current location as the name p->sname */
if( p
->sclass
== EXTDEF
){
printf( " .globl %s\n", exname( p
->sname
) );
if( p
->sclass
== STATIC
&& p
->slevel
>1 ) deflab( p
->offset
);
else printf( "%s:\n", exname( p
->sname
) );
/* put byte i+1 in a string */
if( t
< 0 ){ /* end of the string */
if( i
!= 0 ) fprintf( outfile
, "\n" );
else { /* stash byte t into string */
if( i
== 0 ) fprintf( outfile
, " .byte " );
else fprintf( outfile
, "," );
fprintf( outfile
, "%o", t
);
if( i
== 07 ) fprintf( outfile
, "\n" );
/* n integer words of zeros */
fldal( t
) unsigned t
; { /* return the alignment of field of type t */
uerror( "illegal field type" );
fldty( p
) struct symtab
*p
; { /* fix up type of field p */
where(c
){ /* print location of error */
/* c is either 'u', 'c', or 'w' */
fprintf( stderr
, "%s, line %d: ", ftitle
, lineno
);
char *tmpname
= "/tmp/pcXXXXXX";
main( argc
, argv
) char *argv
[]; {
if( argv
[i
][0] == '-' && argv
[i
][1] == 'X' && argv
[i
][2] == 'p' ) {
if(signal( SIGHUP
, SIG_IGN
) != SIG_IGN
) signal(SIGHUP
, dexit
);
if(signal( SIGINT
, SIG_IGN
) != SIG_IGN
) signal(SIGINT
, dexit
);
if(signal( SIGTERM
, SIG_IGN
) != SIG_IGN
) signal(SIGTERM
, dexit
);
tmpfile
= fopen( tmpname
, "w" );
r
= mainp1( argc
, argv
);
tmpfile
= freopen( tmpname
, "r", tmpfile
);
while((c
=getc(tmpfile
)) != EOF
)
else cerror( "Lost temp file" );
genswitch(p
,n
) register struct sw
*p
;{
/* p points to an array of structures, each consisting
of a constant value and a label.
The first is >=0 if there is a default label;
its value is the label number
The entries p[1] to p[n] are the nontrivial cases
range
= p
[n
].sval
-p
[1].sval
;
if( range
>0 && range
<= 3*n
&& n
>=4 ){ /* implement a direct switch */
dlab
= p
->slab
>= 0 ? p
->slab
: getlab();
printf( CONFMT
, p
[1].sval
);
/* note that this is a cl; it thus checks
for numbers below range as well as out of range.
printf( " cmp r0,$%ld.\n", range
);
printf( " jhi L%d\n", dlab
);
printf( " jmp *L%d(r0)\n", swlab
= getlab() );
for( i
=1,j
=p
[1].sval
; i
<=n
; ++j
){
printf( " L%d\n", ( j
== p
[i
].sval
) ?
if( p
->slab
< 0 ) deflab( dlab
);
if( n >= 4 ) werror( "inefficient switch: %d, %d", n, (int) (range/n) );
printf( CONFMT
, p
[i
].sval
);
printf( ".\n jeq L%d\n", p
[i
].slab
);
if( p
->slab
>=0 ) branch( p
->slab
);