stoasg( p
, o
) register NODE
*p
; {
/* should the assignment op p be stored,
given that it lies as the right operand of o
(or the left, if o==UNARY MUL) */
if( p->op == INCR || p->op == DECR ) return;
if( o==UNARY MUL && p->left->op == REG && !isbreg(p->left->rval) ) SETSTO(p,INAREG);
deltest( p
) register NODE
*p
; {
/* should we delay the INCR or DECR operation p */
return( p
->op
== REG
|| p
->op
== NAME
|| p
->op
== OREG
);
register NODE
*q
= p
->left
, *r
;
if( q
->op
== INCR
&& (r
=q
->left
)->op
== REG
&&
ISPTR(q
->type
) && p
->type
== DECREF(q
->type
) &&
tlen(p
) == q
->right
->lval
) return(1);
mkadrs(p
) register NODE
*p
; {
if( p
->left
->su
>= p
->right
->su
){
if( p
->left
->op
== UNARY MUL
){
SETSTO( p
->left
->left
, INTEMP
);
else if( p
->left
->op
== FLD
&& p
->left
->left
->op
== UNARY MUL
){
SETSTO( p
->left
->left
->left
, INTEMP
);
else { /* should be only structure assignment */
SETSTO( p
->left
, INTEMP
);
else SETSTO( p
->right
, INTEMP
);
if( p
->left
->su
> p
->right
->su
){
SETSTO( p
->left
, INTEMP
);
SETSTO( p
->right
, INTEMP
);
notoff( t
, r
, off
, cp
) CONSZ off
; char *cp
; {
/* is it legal to make an OREG or NAME entry which has an
/* offset of off, (from a register of r), if the
/* resulting thing had type t */
/* if( r == R0 ) return( 1 ); /* NO */
# define max(x,y) ((x)<(y)?(y):(x))
sucomp( p
) register NODE
*p
; {
/* set the su field in the node to the sethi-ullman
number, or local equivalent */
register o
, ty
, sul
, sur
, r
;
p
->su
= szty( p
->type
); /* 2 for float or double, else 1 */;
/* oreg cost is (worst case) 1 + number of temp registers used */
if( R2UPK1(r
)!=100 && istreg(R2UPK1(r
)) ) ++p
->su
;
if( istreg(R2UPK2(r
)) ) ++p
->su
;
if( istreg( r
) ) ++p
->su
;
if( p
->su
== szty(p
->type
) &&
(p
->op
!=REG
|| !istreg(p
->rval
)) &&
(p
->type
==INT
|| p
->type
==UNSIGNED
|| p
->type
==DOUBLE
) )
p
->su
= fregs
; /* all regs needed */
p
->su
= p
->left
->su
+ (szty( p
->type
) > 1 ? 2 : 0) ;
/* If rhs needs n, lhs needs m, regular su computation */
/* computed by doing right, then left (if not in mem), then doing it */
if( o
== CALL
|| o
== STCALL
){
/* in effect, takes all free registers */
p
->su
= max( max( 1+sul
, sur
), fregs
);
/* computed by doing right, doing left address, doing left, op, and store */
if( o==ASG MUL || o==ASG DIV || o==ASG MOD) p->su = max(p->su,fregs);
p
->su
= max( max(sul
,sur
), 1);
/* commutative ops; put harder on left */
if( p
->right
->su
> p
->left
->su
&& !istnode(p
->left
) ){
/* binary op, computed by left, then right, then do op */
p
->su
= max(sul
,szty(p
->right
->type
)+sur
);
if( o==MUL||o==DIV||o==MOD) p->su = max(p->su,fregs);
rallo( p
, down
) NODE
*p
; {
/* do register allocation */
register o
, type
, down1
, down2
, ty
;
if( radebug
) printf( "rallo( %o, %d )\n", p
, down
);
down1
= ( down
&= ~MUSTDO
);
ty
= optype( o
= p
->op
);
if( type
== DOUBLE
|| type
== FLOAT
){
if( o
== FORCE
) down1
= R0
|MUSTDO
;
p->left->rall = down1 = R3|MUSTDO;
if( p->left->op == UNARY MUL ){
rallo( p->left->left, R4|MUSTDO );
else if( p->left->op == FLD && p->left->left->op == UNARY MUL ){
rallo( p->left->left->left, R4|MUSTDO );
else rallo( p->left, R3|MUSTDO );
rallo( p->right, R5|MUSTDO );
if( ty
!= LTYPE
) rallo( p
->left
, down1
);
if( ty
== BITYPE
) rallo( p
->right
, down2
);
offstar( p
) register NODE
*p
; {
if( p
->left
->su
== fregs
) {
order( p
->left
, INTAREG
|INAREG
);
} else if( p
->right
->su
== fregs
) {
order( p
->right
, INTAREG
|INAREG
);
(p
->left
->left
->op
!=REG
|| tlen(p
->left
->left
)!=sizeof(int) ) ) {
order( p
->left
->left
, INTAREG
|INAREG
);
(p
->right
->left
->op
!=REG
|| tlen(p
->right
->left
)!=sizeof(int) ) ) {
order( p
->right
->left
, INTAREG
|INAREG
);
if( p
->type
== (PTR
|CHAR
) || p
->type
== (PTR
|UCHAR
) ) {
if( p
->left
->op
!=REG
|| tlen(p
->left
)!=sizeof(int) ) {
order( p
->left
, INTAREG
|INAREG
);
else if( p
->right
->op
!=REG
|| tlen(p
->right
)!=sizeof(int) ) {
order(p
->right
, INTAREG
|INAREG
);
if( p
->op
== PLUS
|| p
->op
== MINUS
){
if( p
->right
->op
== ICON
){
order( p
, INTAREG
|INAREG
);
if( p
->op
== UNARY MUL
&& !canaddr(p
) ) {
order( p
, INTAREG
|INAREG
);
return( 0 ); /* for the moment, don't bother */
setbin( p
) register NODE
*p
; {
if( canaddr( p
->left
) && !canaddr( p
->right
) ) { /* address rhs */
offstar( p
->right
->left
);
order( p
->right
, INAREG
|INTAREG
|SOREG
);
if( !istnode( p
->left
) ) { /* try putting LHS into a reg */
/* order( p->left, logop(p->op)?(INAREG|INBREG|INTAREG|INTBREG|SOREG):(INTAREG|INTBREG|SOREG) );*/
order( p
->left
, INAREG
|INTAREG
|INBREG
|INTBREG
|SOREG
);
else if( ro
== UNARY MUL
&& rt
!= CHAR
&& rt
!= UCHAR
){
offstar( p
->right
->left
);
else if( rt
== CHAR
|| rt
== UCHAR
|| rt
== SHORT
|| rt
== USHORT
|| (ro
!= REG
&&
ro
!= NAME
&& ro
!= OREG
&& ro
!= ICON
) ){
order( p
->right
, INAREG
|INBREG
);
else if( logop(p->op) && rt==USHORT ){ /* must get rhs into register */
order( p->right, INAREG );
setstr( p
) register NODE
*p
; { /* structure assignment */
if( p
->right
->op
!= REG
){
order( p
->right
, INTAREG
);
if( p
->op
!= NAME
&& p
->op
!= OREG
){
if( p
->op
!= UNARY MUL
) cerror( "bad setstr" );
order( p
->left
, INTAREG
);
setasg( p
) register NODE
*p
; {
/* setup for assignment operator */
if( !canaddr(p
->right
) ) {
if( p
->right
->op
== UNARY MUL
)
order( p
->right
, INAREG
|INBREG
|SOREG
);
if( p
->left
->op
== UNARY MUL
) {
offstar( p
->left
->left
);
if( p
->left
->op
== FLD
&& p
->left
->left
->op
== UNARY MUL
){
offstar( p
->left
->left
->left
);
if( p
->left
->op
== FLD
&& !(p
->right
->type
==INT
|| p
->right
->type
==UNSIGNED
)) {
order( p
->right
, INAREG
);
setasop( p
) register NODE
*p
; {
if( ro
== UNARY MUL
&& rt
!= CHAR
){
offstar( p
->right
->left
);
if( ( rt
== CHAR
|| rt
== SHORT
|| rt
== UCHAR
|| rt
== USHORT
||
( ro
!= REG
&& ro
!= ICON
&& ro
!= NAME
&& ro
!= OREG
) ) ){
order( p
->right
, INAREG
|INBREG
);
if( (p->op == ASG LS || p->op == ASG RS) && ro != ICON && ro != REG ){
order( p->right, INAREG );
if( p
->op
== FLD
) p
= p
->left
;
cerror( "illegal setasop" );
int crslab
= 9999; /* Honeywell */
genargs( p
, ptemp
) register NODE
*p
, *ptemp
; {
/* generate code for the arguments */
/* first, do the arguments on the right */
genargs( p
->right
, ptemp
);
if( p
->op
== STARG
){ /* structure valued argument */
if( p
->left
->op
== ICON
){
/* make it look beautiful... */
canon( p
); /* turn it into an oreg */
if( p
->op
!= OREG
) cerror( "stuck starg" );
ptemp
->lval
= 0; /* all moves to (sp) */
pasg
->left
= tcopy( ptemp
);
/* the following line is done only with the knowledge
that it will be undone by the STASG node, with the
offset (lval) field retained */
if( p
->op
== OREG
) p
->op
= REG
; /* only for temporaries */
argsize( p
) register NODE
*p
; {
if( p
->type
== DOUBLE
|| p
->type
== FLOAT
){
else if( p
->op
== STARG
){
SETOFF( t
, 4 ); /* alignment */
return( t
+ ((p
->stsize
+3)/4)*4 ); /* size */