/* a lot of the machine dependent parts of the second pass */
# define BITMASK(n) ((1L<<n)-1)
fprintf( stderr
, "%s, line %d: ", filename
, lineno
);
lineid( l
, fn
) char *fn
; {
/* identify line l and file fn */
printf( "# line %d, file %s\n", l
, fn
);
OFFSZ spoff
; /* offset from stack pointer */
if( spoff
>= AUTOINIT
) spoff
-= AUTOINIT
;
printf( " .set .F%d,%ld\n", ftnno
, spoff
);
extern int ftlab1
, ftlab2
;
if( spoff
>= AUTOINIT
) spoff
-= AUTOINIT
;
printf( "L%d:\n", ftlab1
);
printf( " subl2 $%ld,sp\n", spoff
);
printf( " movab -%ld(sp),sp\n", spoff
);
printf( " jbr L%d\n", ftlab2
);
struct hoptab
{ int opmask
; char * opstring
; } ioptab
[] = {
/* output the appropriate string from the above table */
register struct hoptab
*q
;
for( q
= ioptab
; q
->opmask
>=0; ++q
){
printf( "%s", q
->opstring
);
if( f == 'F' ) printf( "e" );
else if( f == 'D' ) printf( "d" );
printf("%c", tolower(f
));
cerror( "no hoptab for %s", opst
[o
] );
rnames
[] = { /* keyed to register number tokens */
"r6", "r7", "r8", "r9", "r10", "r11",
SAREG
|STAREG
, SAREG
|STAREG
,
SAREG
|STAREG
, SAREG
|STAREG
, SAREG
|STAREG
, SAREG
|STAREG
,
SAREG
, SAREG
, SAREG
, SAREG
, SAREG
, SAREG
,
SAREG
, SAREG
, SAREG
, SAREG
,
mixtypes(p
, q
) NODE
*p
, *q
;
return( (tp
==FLOAT
|| tp
==DOUBLE
) !=
(tq
==FLOAT
|| tq
==DOUBLE
) );
if ( !ISPTR( n
->type
) ) cerror("zzzcode- bad type");
zzzcode( p
, c
) register NODE
*p
; {
case 'N': /* logical ops, turned into 0-1 */
/* use register given by register 1 */
cbgen( 0, m
=getlab(), 'I' );
printf( " clrl %s\n", rnames
[getlr( p
, '1' )->rval
] );
cbgen( p
->op
, p
->label
, c
);
if (xdebug
) eprint(p
, 0, &val
, &val
);
if (optype(p
->op
) == LTYPE
|| p
->op
== UNARY MUL
)
l
->type
= (r
->type
==FLOAT
|| r
->type
==DOUBLE
? DOUBLE
: INT
);
if (r
->op
== ICON
&& r
->name
[0] == '\0')
if (r
->lval
< 0 && r
->lval
>= -63)
: (r
->lval
>= -32768 ? SHORT
r
->type
= (r
->lval
>= 0 ?
: ( r
->lval
<= 127 ? CHAR
: (r
->lval
<= 255 ? UCHAR
: (r
->lval
<= 32767 ? SHORT
: (r
->lval
<= 65535 ? USHORT
if (l
->op
== REG
&& l
->type
!= FLOAT
&& l
->type
!= DOUBLE
)
else if (tlen(l
) > tlen(r
) && ISUNSIGNED(r
->type
))
case 'C': /* num words pushed on arg stack */
if (xdebug
) printf("->%d<-",gc_numbytes
);
printf("$%d", gc_numbytes
/(SZLONG
/SZCHAR
) );
case 'D': /* INCR and DECR */
case 'E': /* INCR and DECR, FOREFF */
printf("%s", (p
->op
== INCR
? "inc" : "dec") );
printf("%s", (p
->op
== INCR
? "add" : "sub") );
case 'F': /* register type of right operand */
if (xdebug
) printf("->%d<-", ty
);
if ( ty
==DOUBLE
) printf("d");
else if ( ty
==FLOAT
) printf("f");
case 'L': /* type of left operand */
case 'R': /* type of right operand */
if (xdebug
) printf("->%d<-", n
->type
);
case 'Z': /* complement mask for bit instr */
printf("$%ld", ~p
->right
->lval
);
case 'U': /* 32 - n, for unsigned right shifts */
printf("$%d", 32 - p
->right
->lval
);
case 'T': /* rounded structure length for arguments */
case 'S': /* structure assignment */
else if( p
->op
== STARG
){ /* store an arg into a temporary */
else cerror( "STASG bad" );
if( r
->op
== ICON
) r
->op
= NAME
;
else if( r
->op
== REG
) r
->op
= OREG
;
else if( r
->op
!= OREG
) cerror( "STASG-r" );
if( size
<= 0 || size
> 65535 )
cerror("structure size <0=0 or >65535");
printf(" movc3 $%d,", size
);
if( r
->op
== NAME
) r
->op
= ICON
;
else if( r
->op
== OREG
) r
->op
= REG
;
cerror( "illegal zzzcode" );
(t
==FLOAT
? "movf" : (t
==DOUBLE
? "movd" : "movl")),
rnames
[rs
], rnames
[rt
] );
INTAREG
|INTBREG
, INTAREG
|INTBREG
,
INAREG
|INBREG
, INAREG
|INBREG
|SOREG
|STARREG
|STARNM
|SNAME
|SCON
,
INTEMP
, INTAREG
|INAREG
|INTBREG
|INBREG
|SOREG
|STARREG
|STARNM
,
setregs(){ /* set up temporary registers */
fregs
= 6; /* tbl- 6 free regs on VAX (0-5) */
szty(t
){ /* size, in registers, needed to hold thing of type t */
return( (t
==DOUBLE
||t
==FLOAT
) ? 2 : 1 );
base( p
) register NODE
*p
; {
if( (o
==ICON
&& p
->name
[0] != '\0')) return( 100 ); /* ie no base reg */
if( o
==REG
) return( p
->rval
);
if( (o
==PLUS
|| o
==MINUS
) && p
->left
->op
== REG
&& p
->right
->op
==ICON
)
if( o
==OREG
&& !R2TEST(p
->rval
) && (p
->type
==INT
|| p
->type
==UNSIGNED
|| ISPTR(p
->type
)) )
return( p
->rval
+ 0200*1 );
if( o
==INCR
&& p
->left
->op
==REG
) return( p
->left
->rval
+ 0200*2 );
if( o
==ASG MINUS
&& p
->left
->op
==REG
) return( p
->left
->rval
+ 0200*4 );
if( o
==UNARY MUL
&& p
->left
->op
==INCR
&& p
->left
->left
->op
==REG
&& (p
->type
==INT
|| p
->type
==UNSIGNED
|| ISPTR(p
->type
)) )
return( p
->left
->left
->rval
+ 0200*(1+2) );
offset( p
, tyl
) register NODE
*p
; int tyl
; {
if( tyl
==1 && p
->op
==REG
&& (p
->type
==INT
|| p
->type
==UNSIGNED
) ) return( p
->rval
);
if( (p
->op
==LS
&& p
->left
->op
==REG
&& (p
->left
->type
==INT
|| p
->left
->type
==UNSIGNED
) &&
(p
->right
->op
==ICON
&& p
->right
->name
[0]=='\0')
&& (1<<p
->right
->lval
)==tyl
))
makeor2( p
, q
, b
, o
) register NODE
*p
, *q
; register int b
, o
; {
f
= p
->left
; /* have to free this subtree later */
q
->right
->lval
= -q
->right
->lval
;
cerror("illegal makeor2");
p
->rval
= R2PACK( (b
& 0177), o
, (b
>>7) );
if( o
==NAME
|| o
==REG
|| o
==ICON
|| o
==OREG
|| (o
==UNARY MUL
&& shumul(p
->left
)) ) return(1);
shltype( o
, p
) register NODE
*p
; {
return( o
== REG
|| o
== NAME
|| o
== ICON
|| o
== OREG
|| ( o
==UNARY MUL
&& shumul(p
->left
)) );
flshape( p
) register NODE
*p
; {
return( p
->op
== REG
|| p
->op
== NAME
|| p
->op
== ICON
||
(p
->op
== OREG
&& (!R2TEST(p
->rval
) || tlen(p
) == 1)) );
shtemp( p
) register NODE
*p
; {
if( p
->op
== STARG
) p
= p
->left
;
return( p
->op
==NAME
|| p
->op
==ICON
|| p
->op
== OREG
|| (p
->op
==UNARY MUL
&& shumul(p
->left
)) );
shumul( p
) register NODE
*p
; {
printf("\nshumul:op=%d,lop=%d,rop=%d", p
->op
, p
->left
->op
, p
->right
->op
);
printf(" prname=%s,plty=%d, prlval=%D\n", p
->right
->name
, p
->left
->type
, p
->right
->lval
);
if( o
== NAME
|| (o
== OREG
&& !R2TEST(p
->rval
)) || o
== ICON
) return( STARNM
);
if( ( o
== INCR
|| o
== ASG MINUS
) &&
( p
->left
->op
== REG
&& p
->right
->op
== ICON
) &&
p
->right
->name
[0] == '\0' )
if ( ISPTR(p
->left
->type
) ) {
return( p
->right
->lval
== o
? STARREG
: 0);
adrcon( val
) CONSZ val
; {
conput( p
) register NODE
*p
; {
printf( "%s", rnames
[p
->rval
] );
cerror( "illegal conput" );
insput( p
) register NODE
*p
; {
upput( p
) register NODE
*p
; {
adrput( p
) register NODE
*p
; {
/* output an address, with offsets, from p */
/* addressable value of the constant */
printf( "%s", rnames
[p
->rval
] );
if( R2TEST(r
) ){ /* double indexing */
if( flags
& 1 ) printf("*");
if( flags
& 4 ) printf("-");
if( p
->lval
!= 0 || p
->name
[0] != '\0' ) acon(p
);
if( R2UPK1(r
) != 100) printf( "(%s)", rnames
[R2UPK1(r
)] );
if( flags
& 2 ) printf("+");
printf( "[%s]", rnames
[R2UPK2(r
)] );
if( r
== AP
){ /* in the argument region */
if( p
->lval
<= 0 || p
->name
[0] != '\0' ) werror( "bad arg temp" );
printf( CONFMT
, p
->lval
);
if( p
->lval
!= 0 || p
->name
[0] != '\0') acon( p
);
printf( "(%s)", rnames
[p
->rval
] );
/* STARNM or STARREG found */
if( tshape(p
, STARNM
) ) {
else { /* STARREG - really auto inc or dec */
printf("(%s)", rnames
[p
->left
->left
->rval
]);
p
->rval
= p
->left
->left
->rval
;
p
->lval
= (p
->left
->op
== INCR
? -p
->left
->right
->lval
: 0);
cerror( "illegal address" );
acon( p
) register NODE
*p
; { /* print out a constant */
if( p
->name
[0] == '\0' ){
printf( CONFMT
, p
->lval
);
else if( p
->lval
== 0 ) {
printf( "%.8s", p
->name
);
printf( "%.8s+", p
->name
);
printf( CONFMT
, p
->lval
);
aacon( p ) register NODE *p; { /* print out a constant */
if( p->name[0] == '\0' ){
printf( CONFMT, p->lval);
else if( p->lval == 0 ) {
printf( "$%.8s", p->name );
printf( CONFMT, p->lval );
printf( "%.8s)", p->name );
genscall( p
, cookie
) register NODE
*p
; {
/* structure valued call */
return( gencall( p
, cookie
) );
gencall( p
, cookie
) register NODE
*p
; {
/* generate the call given by p */
register NODE
*p1
, *ptemp
;
if( p
->right
) temp
= argsize( p
->right
);
if( p
->op
== STCALL
|| p
->op
== UNARY STCALL
){
/* set aside room for structure return */
if( p
->stsize
> temp
) temp1
= p
->stsize
;
if( temp
> maxargs
) maxargs
= temp
;
if( p
->right
){ /* make temp node, put offset in, and generate args */
genargs( p
->right
, ptemp
);
if( p1
->op
!= OREG
|| R2TEST(p1
->rval
) ){
if( p1->op == REG && p->rval == R5 ){
cerror( "call register overwrite" );
setup gc_numbytes so reference to ZC works */
m
= match( p
, INTAREG
|INTBREG
);
printf( " tst (sp)+\n" );
printf( " cmp (sp)+,(sp)+\n" );
printf( " add $%d,sp\n", temp);
cbgen( o
, lab
, mode
) { /* printf conditional and unconditional branches */
if( o
== 0 ) printf( " jbr L%d\n", lab
);
if( o
> UGT
) cerror( "bad conditional branch: %s", opst
[o
] );
printf( ccbranches
[o
-EQ
], lab
);
nextcook( p
, cookie
) NODE
*p
; {
/* we have failed to match p with cookie; try another */
if( cookie
== FORREW
) return( 0 ); /* hopeless! */
if( !(cookie
&(INTAREG
|INTBREG
)) ) return( INTAREG
|INTBREG
);
if( !(cookie
&INTEMP
) && asgop(p
->op
) ) return( INTEMP
|INAREG
|INTAREG
|INTBREG
|INBREG
);
lastchance( p
, cook
) NODE
*p
; {
optim2( p
) register NODE
*p
; {
/* do local tree transformations and optimizations */
/* commute L and R to eliminate compliments and constants */
if( (p
->left
->op
==ICON
&&p
->left
->name
[0]==0) || p
->left
->op
==COMPL
) {
/* change meaning of AND to ~R&L - bic on pdp11 */
if( r
->op
==ICON
&& r
->name
[0]==0 ) { /* compliment constant */
else if( r
->op
==COMPL
) { /* ~~A => A */
else { /* insert complement node */
p
->right
->type
= r
->type
;
main( argc
, argv
) char *argv
[]; {
return( mainp2( argc
, argv
) );