|
|
Power 6/32 Unix version 1.2b
# include "mfile2"
# include "ctype.h"
# ifdef FORT
int ftlab1, ftlab2;
# endif
/* a lot of the machine dependent parts of the second pass */
# define BITMASK(n) ((1L<<n)-1)
# ifndef ONEPASS
where(c){
fprintf( stderr, "%s, line %d: ", filename, lineno );
}
# endif
lineid( l, fn ) char *fn; {
/* identify line l and file fn */
printf( "# line %d, file %s\n", l, fn );
}
int ent_mask;
eobl2(){
register OFFSZ spoff; /* offset from stack pointer */
#ifndef FORT
extern int ftlab1, ftlab2;
#endif
spoff = maxoff;
spoff /= SZCHAR;
SETOFF(spoff,4);
#ifdef FORT
#ifndef FLEXNAMES
printf( " .set .F%d,%d\n", ftnno, spoff );
#else
/* SHOULD BE L%d ... ftnno but must change pc/f77 */
printf( " .set LF%d,%d\n", ftnno, spoff );
#endif
printf( " .set LWM%d,0x%x\n", ftnno, ent_mask&0x1ffc|0x1000);
#else
printf( " .set L%d,0x%x\n", ftnno, ent_mask&0x1ffc);
printf( "L%d:\n", ftlab1);
if( maxoff > AUTOINIT )
printf( " subl3 $%d,fp,sp\n", spoff);
printf( " jbr L%d\n", ftlab2);
#endif
ent_mask = 0;
maxargs = -1;
}
struct hoptab { int opmask; char * opstring; } ioptab[] = {
ASG PLUS, "add",
ASG MINUS, "sub",
ASG MUL, "mul",
ASG DIV, "div",
ASG OR, "or",
ASG ER, "xor",
ASG AND, "and",
PLUS, "add",
MINUS, "sub",
MUL, "mul",
DIV, "div",
OR, "or",
ER, "xor",
AND, "and",
-1, "" };
hopcode( f, o ){
/* output the appropriate string from the above table */
register struct hoptab *q;
for( q = ioptab; q->opmask>=0; ++q ){
if( q->opmask == o ){
printf( "%s%c", q->opstring, tolower(f));
return;
}
}
cerror( "no hoptab for %s", opst[o] );
}
char *
rnames[] = { /* keyed to register number tokens */
"r0", "r1",
"r2", "r3", "r4", "r5",
"r6", "r7", "r8", "r9", "r10", "r11",
"r12", "fp", "sp", "pc",
};
/* output register name and update entry mask */
char *
rname(r)
register r;
{
ent_mask |= 1<<r;
return(rnames[r]);
}
int rstatus[] = {
SAREG|STAREG, SAREG|STAREG,
SAREG|STAREG, SAREG|STAREG, SAREG|STAREG, SAREG|STAREG,
SAREG, SAREG, SAREG, SAREG, SAREG, SAREG,
SAREG, SAREG, SAREG, SAREG,
};
tlen(p) NODE *p;
{
switch(p->in.type) {
case CHAR:
case UCHAR:
return(1);
case SHORT:
case USHORT:
return(2);
case DOUBLE:
return(8);
default:
return(4);
}
}
mixtypes(p, q) NODE *p, *q;
{
register tp, tq;
tp = p->in.type;
tq = q->in.type;
return( (tp==FLOAT || tp==DOUBLE) !=
(tq==FLOAT || tq==DOUBLE) );
}
prtype(n) NODE *n;
{
switch (n->in.type)
{
case DOUBLE:
case FLOAT:
case INT:
case UNSIGNED:
printf("l");
return;
case SHORT:
case USHORT:
printf("w");
return;
case CHAR:
case UCHAR:
printf("b");
return;
default:
if ( !ISPTR( n->in.type ) ) cerror("zzzcode- bad type");
else {
printf("l");
return;
}
}
}
zzzcode( p, c ) register NODE *p; {
register m;
int val;
switch( c ){
case 'N': /* logical ops, turned into 0-1 */
/* use register given by register 1 */
cbgen( 0, m=getlab(), 'I' );
deflab( p->bn.label );
printf( " clrl %s\n", rname(getlr( p, '1' )->tn.rval) );
deflab( m );
return;
case 'P':
cbgen( p->in.op, p->bn.label, c );
return;
case 'A':
{
register NODE *l, *r;
if (xdebug) eprint(p, 0, &val, &val);
r = getlr(p, 'R');
if (optype(p->in.op) == LTYPE || p->in.op == UNARY MUL) {
l = resc;
l->in.type = (r->in.type==FLOAT || r->in.type==DOUBLE ? DOUBLE : INT);
} else
l = getlr(p, 'L');
if (r->in.op == ICON)
if(r->in.name[0] == '\0') {
if (r->tn.lval == 0) {
printf("clr");
prtype(l);
printf(" ");
adrput(l);
return;
}
if (r->tn.lval < 0 && r->tn.lval >= -63) {
printf("mneg");
prtype(l);
r->tn.lval = -r->tn.lval;
goto ops;
}
#ifdef MOVAFASTER
} else {
printf("movab");
printf(" ");
acon(r);
printf(",");
adrput(l);
return;
#endif MOVAFASTER
}
if (l->in.op == REG && l->in.type != FLOAT && l->in.type != DOUBLE) {
if( tlen(l) < tlen(r) ) {
if (!mixtypes(l,r)) {
!ISUNSIGNED(l->in.type)?
printf("cvt"):
printf("movz");
prtype(l);
printf("l");
goto ops;
} else {
cerror("mixed types");
return;
}
} else {
l->in.type = INT;
}
}
if (!mixtypes(l,r)) {
if (tlen(l) == tlen(r)) {
printf("mov");
prtype(l);
goto ops;
} else if (tlen(l) > tlen(r) && ISUNSIGNED(r->in.type)) {
printf("movz");
} else {
if (l->in.type != FLOAT && l->in.type != DOUBLE)
printf("cvt");
else {
if(l->in.type == DOUBLE) {
printf("clrl ");
upput(l);
printf("\n ");
}
printf("movl");
goto ops;
}
}
} else {
cerror("mixed types");
}
prtype(r);
prtype(l);
ops:
printf(" ");
adrput(r);
printf(",");
adrput(l);
return;
}
case 'B': /* get oreg value in temp register for shift */
{
register NODE *r;
if (xdebug) eprint(p, 0, &val, &val);
r = p->in.right;
if( tlen(r) == sizeof(int) && r->in.type != FLOAT )
printf("movl");
else {
printf(ISUNSIGNED(r->in.type) ? "movz" : "cvt");
prtype(r);
printf("l");
}
return;
}
case 'C': /* num bytes pushed on arg stack */
{
extern int gc_numbytes;
extern int xdebug;
if (xdebug) printf("->%d<-",gc_numbytes);
printf("call%c $%d",
(p->in.left->in.op==ICON && gc_numbytes<60)?'f':'s',
gc_numbytes+4);
return;
}
case 'D': /* INCR and DECR */
zzzcode(p->in.left, 'A');
printf("\n ");
case 'E': /* INCR and DECR, FOREFF */
if (p->in.right->tn.lval == 1)
{
printf("%s", (p->in.op == INCR ? "inc" : "dec") );
prtype(p->in.left);
printf(" ");
adrput(p->in.left);
return;
}
printf("%s", (p->in.op == INCR ? "add" : "sub") );
prtype(p->in.left);
printf("2 ");
adrput(p->in.right);
printf(",");
adrput(p->in.left);
return;
case 'F': /* masked constant for fields */
printf("$%d", (p->in.right->tn.lval&((1<<fldsz)-1))<<fldshf);
return;
case 'H': /* opcode for shift */
if(p->in.op == LS || p->in.op == ASG LS)
printf("shll");
else if(ISUNSIGNED(p->in.left->in.type))
printf("shrl");
else
printf("shar");
return;
case 'L': /* type of left operand */
case 'R': /* type of right operand */
{
register NODE *n;
extern int xdebug;
n = getlr ( p, c);
if (xdebug) printf("->%d<-", n->in.type);
prtype(n);
return;
}
case 'M': /* initiate ediv for mod and unsigned div */
{
register char *r;
m = getlr(p, '1')->tn.rval;
r = rname(m);
printf("\tclrl\t%s\n\tmovl\t", r);
adrput(p->in.left);
printf(",%s\n", rname(m+1));
if(!ISUNSIGNED(p->in.type)) { /* should be MOD */
m = getlab();
printf("\tjgeq\tL%d\n\tmnegl\t$1,%s\n", m, r);
deflab(m);
}
}
return;
case 'U':
/* Truncate int for type conversions:
LONG|ULONG -> CHAR|UCHAR|SHORT|USHORT
SHORT|USHORT -> CHAR|UCHAR
increment offset to correct byte */
{
register NODE *p1;
int dif;
p1 = p->in.left;
switch( p1->in.op ){
case NAME:
case OREG:
dif = tlen(p1)-tlen(p);
p1->tn.lval += dif;
adrput(p1);
p1->tn.lval -= dif;
return;
default:
cerror( "Illegal ZU type conversion" );
return;
}
}
case 'T': /* rounded structure length for arguments */
{
int size;
size = p->stn.stsize;
SETOFF( size, 4);
printf("movab -%d(sp),sp", size);
return;
}
case 'S': /* structure assignment */
{
register NODE *l, *r;
register size;
if( p->in.op == STASG ){
l = p->in.left;
r = p->in.right;
}
else if( p->in.op == STARG ){ /* store an arg into a temporary */
l = getlr( p, '3' );
r = p->in.left;
}
else cerror( "STASG bad" );
if( r->in.op == ICON ) r->in.op = NAME;
else if( r->in.op == REG ) r->in.op = OREG;
else if( r->in.op != OREG ) cerror( "STASG-r" );
size = p->stn.stsize;
if( size <= 0 || size > 65535 )
cerror("structure size <0=0 or >65535");
switch(size) {
case 1:
printf(" movb ");
break;
case 2:
printf(" movw ");
break;
case 4:
printf(" movl ");
break;
case 8:
printf(" movl ");
upput(r);
printf(",");
upput(l);
printf("\n movl ");
break;
default:
printf(" movab ");
adrput(r);
printf(",r0\n movab ");
adrput(l);
printf(",r1\n movl $%d,r2\n movblk\n", size);
goto endstasg;
}
adrput(r);
printf(",");
adrput(l);
printf("\n");
endstasg:
if( r->in.op == NAME ) r->in.op = ICON;
else if( r->in.op == OREG ) r->in.op = REG;
}
break;
default:
cerror( "illegal zzzcode" );
}
}
rmove( rt, rs, t ) TWORD t;{
printf( " movl %s,%s\n", rname(rs), rname(rt) );
if(t==DOUBLE)
printf( " movl %s,%s\n", rname(rs+1), rname(rt+1) );
}
struct respref
respref[] = {
INTAREG|INTBREG, INTAREG|INTBREG,
INAREG|INBREG, INAREG|INBREG|SOREG|STARREG|STARNM|SNAME|SCON,
INTEMP, INTEMP,
FORARG, FORARG,
INTEMP, INTAREG|INAREG|INTBREG|INBREG|SOREG|STARREG|STARNM,
0, 0 };
setregs(){ /* set up temporary registers */
fregs = 6; /* tbl- 6 free regs on Tahoe (0-5) */
}
szty(t) TWORD t;{ /* size, in registers, needed to hold thing of type t */
return( (t==DOUBLE||t==FLOAT) ? 2 : 1 );
}
rewfld( p ) NODE *p; {
return(1);
}
callreg(p) NODE *p; {
return( R0 );
}
base( p ) register NODE *p; {
register int o = p->in.op;
if( (o==ICON && p->in.name[0] != '\0')) return( 100 ); /* ie no base reg */
if( o==REG ) return( p->tn.rval );
if( (o==PLUS || o==MINUS) && p->in.left->in.op == REG && p->in.right->in.op==ICON)
return( p->in.left->tn.rval );
if( o==OREG && !R2TEST(p->tn.rval) && (p->in.type==INT || p->in.type==UNSIGNED || ISPTR(p->in.type)) )
return( p->tn.rval + 0200*1 );
return( -1 );
}
offset( p, tyl ) register NODE *p; int tyl; {
if(tyl > 4) return( -1 );
if( tyl==1 && p->in.op==REG && (p->in.type==INT || p->in.type==UNSIGNED) ) return( p->tn.rval );
if( (p->in.op==LS && p->in.left->in.op==REG && (p->in.left->in.type==INT || p->in.left->in.type==UNSIGNED) &&
(p->in.right->in.op==ICON && p->in.right->in.name[0]=='\0')
&& (1<<p->in.right->tn.lval)==tyl))
return( p->in.left->tn.rval );
return( -1 );
}
makeor2( p, q, b, o) register NODE *p, *q; register int b, o; {
register NODE *t;
register int i;
NODE *f;
p->in.op = OREG;
f = p->in.left; /* have to free this subtree later */
/* init base */
switch (q->in.op) {
case ICON:
case REG:
case OREG:
t = q;
break;
case MINUS:
q->in.right->tn.lval = -q->in.right->tn.lval;
case PLUS:
t = q->in.right;
break;
case UNARY MUL:
t = q->in.left->in.left;
break;
default:
cerror("illegal makeor2");
}
p->tn.lval = t->tn.lval;
#ifndef FLEXNAMES
for(i=0; i<NCHNAM; ++i)
p->in.name[i] = t->in.name[i];
#else
p->in.name = t->in.name;
#endif
/* init offset */
p->tn.rval = R2PACK( (b & 0177), o, (b>>7) );
tfree(f);
return;
}
canaddr( p ) NODE *p; {
register int o = p->in.op;
if( o==NAME || o==REG || o==ICON || o==OREG || (o==UNARY MUL && shumul(p->in.left)) ) return(1);
return(0);
}
shltype( o, p ) register NODE *p; {
return( o== REG || o == NAME || o == ICON || o == OREG || ( o==UNARY MUL && shumul(p->in.left)) );
}
flshape( p ) NODE *p; {
register int o = p->in.op;
if( o==NAME || o==REG || o==ICON || o==OREG || (o==UNARY MUL && shumul(p->in.left)) ) return(1);
return(0);
}
shtemp( p ) register NODE *p; {
if( p->in.op == STARG ) p = p->in.left;
return( p->in.op==NAME || p->in.op ==ICON || p->in.op == OREG || (p->in.op==UNARY MUL && shumul(p->in.left)) );
}
shumul( p ) register NODE *p; {
register o;
extern int xdebug;
if (xdebug) {
printf("\nshumul:op=%d,lop=%d,rop=%d", p->in.op, p->in.left->in.op, p->in.right->in.op);
printf(" prname=%s,plty=%d, prlval=%D\n", p->in.right->in.name, p->in.left->in.type, p->in.right->tn.lval);
}
o = p->in.op;
if(( o == NAME || (o == OREG && !R2TEST(p->tn.rval)) || o == ICON )
&& p->in.type != PTR+DOUBLE)
return( STARNM );
return( 0 );
}
adrcon( val ) CONSZ val; {
printf( "$" );
printf( CONFMT, val );
}
conput( p ) register NODE *p; {
switch( p->in.op ){
case ICON:
acon( p );
return;
case REG:
printf( "%s", rname(p->tn.rval) );
return;
default:
cerror( "illegal conput" );
}
}
insput( p ) NODE *p; {
cerror( "insput" );
}
upput( p ) register NODE *p; {
/* output the address of the second long in the
pair pointed to by p (for DOUBLEs)*/
CONSZ save;
if( p->in.op == FLD ){
p = p->in.left;
}
switch( p->in.op ){
case NAME:
case OREG:
save = p->tn.lval;
p->tn.lval += SZLONG/SZCHAR;
adrput(p);
p->tn.lval = save;
return;
case REG:
printf( "%s", rname(p->tn.rval+1) );
return;
default:
cerror( "illegal upper address" );
}
}
adrput( p ) register NODE *p; {
register int r;
/* output an address, with offsets, from p */
if( p->in.op == FLD ){
p = p->in.left;
}
switch( p->in.op ){
case NAME:
acon( p );
return;
case ICON:
/* addressable value of the constant */
printf( "$" );
acon( p );
return;
case REG:
printf( "%s", rname(p->tn.rval) );
return;
case OREG:
r = p->tn.rval;
if( R2TEST(r) ){ /* double indexing */
register int flags;
flags = R2UPK3(r);
if( flags & 1 ) printf("*");
if( p->tn.lval != 0 || p->in.name[0] != '\0' ) acon(p);
if( R2UPK1(r) != 100) printf( "(%s)", rname(R2UPK1(r)) );
printf( "[%s]", rname(R2UPK2(r)) );
return;
}
if( r == FP && p->tn.lval > 0 ){ /* in the argument region */
if( p->in.name[0] != '\0' ) werror( "bad arg temp" );
printf( CONFMT, p->tn.lval );
printf( "(fp)" );
return;
}
if( p->tn.lval != 0 || p->in.name[0] != '\0') acon( p );
printf( "(%s)", rname(p->tn.rval) );
return;
case UNARY MUL:
/* STARNM or STARREG found */
if( tshape(p, STARNM) ) {
printf( "*" );
adrput( p->in.left);
}
return;
default:
cerror( "illegal address" );
return;
}
}
acon( p ) register NODE *p; { /* print out a constant */
if( p->in.name[0] == '\0' ){
printf( CONFMT, p->tn.lval);
}
else if( p->tn.lval == 0 ) {
#ifndef FLEXNAMES
printf( "%.8s", p->in.name );
#else
printf( "%s", p->in.name );
#endif
}
else {
#ifndef FLEXNAMES
printf( "%.8s+", p->in.name );
#else
printf( "%s+", p->in.name );
#endif
printf( CONFMT, p->tn.lval );
}
}
genscall( p, cookie ) register NODE *p; {
/* structure valued call */
return( gencall( p, cookie ) );
}
/* tbl */
int gc_numbytes;
/* tbl */
gencall( p, cookie ) register NODE *p; {
/* generate the call given by p */
register NODE *p1, *ptemp;
register temp, temp1;
register m;
if( p->in.right ) temp = argsize( p->in.right );
else temp = 0;
if( p->in.op == STCALL || p->in.op == UNARY STCALL ){
/* set aside room for structure return */
if( p->stn.stsize > temp ) temp1 = p->stn.stsize;
else temp1 = temp;
}
if( temp > maxargs ) maxargs = temp;
SETOFF(temp1,4);
if( p->in.right ){ /* make temp node, put offset in, and generate args */
ptemp = talloc();
ptemp->in.op = OREG;
ptemp->tn.lval = -1;
ptemp->tn.rval = SP;
#ifndef FLEXNAMES
ptemp->in.name[0] = '\0';
#else
ptemp->in.name = "";
#endif
ptemp->in.rall = NOPREF;
ptemp->in.su = 0;
genargs( p->in.right, ptemp );
ptemp->in.op = FREE;
}
p1 = p->in.left;
if( p1->in.op != ICON ){
if( p1->in.op != REG ){
if( p1->in.op != OREG || R2TEST(p1->tn.rval) ){
if( p1->in.op != NAME ){
order( p1, INAREG );
}
}
}
}
/* tbl
setup gc_numbytes so reference to ZC works */
gc_numbytes = temp&(0x3ff);
p->in.op = UNARY CALL;
m = match( p, INTAREG|INTBREG );
return(m != MDONE);
}
/* tbl */
char *
ccbranches[] = {
"eql",
"neq",
"leq",
"lss",
"geq",
"gtr",
"lequ",
"lssu",
"gequ",
"gtru",
};
/* tbl */
cbgen( o, lab, mode ) { /* printf conditional and unconditional branches */
if(o != 0 && (o < EQ || o > UGT ))
cerror( "bad conditional branch: %s", opst[o] );
printf( " j%s L%d\n",
o == 0 ? "br" : 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->in.op) ) return( INTEMP|INAREG|INTAREG|INTBREG|INBREG );
return( FORREW );
}
lastchance( p, cook ) NODE *p; {
/* forget it! */
return(0);
}
optim2( p ) register NODE *p; {
# ifdef ONEPASS
/* do local tree transformations and optimizations */
# define RV(p) p->in.right->tn.lval
register o = p->in.op;
register i;
/* change unsigned mods and divs to logicals (mul is done in mip & c2) */
if(optype(o) == BITYPE && ISUNSIGNED(p->in.left->in.type)
&& nncon(p->in.right) && (i=ispow2(RV(p)))>=0){
switch(o) {
case DIV:
case ASG DIV:
p->in.op = RS;
RV(p) = i;
break;
case MOD:
case ASG MOD:
p->in.op = AND;
RV(p)--;
break;
default:
return;
}
if(asgop(o))
p->in.op = ASG p->in.op;
}
# endif
}
NODE * addroreg(l) NODE *l;
/* OREG was built in clocal()
* for an auto or formal parameter
* now its address is being taken
* local code must unwind it
* back to PLUS/MINUS REG ICON
* according to local conventions
*/
{
cerror("address of OREG taken");
}
# ifndef ONEPASS
main( argc, argv ) char *argv[]; {
return( mainp2( argc, argv ) );
}
# endif
struct functbl {
int fop;
char *funcf, *funcd;
} opfunc[] = {
PLUS, "Xaddf", "Xaddd",
MINUS, "Xsubf", "Xsubd",
MUL, "Xmulf", "Xmuld",
DIV, "Xdivf", "Xdivd",
ASG PLUS, "Xaddf", "Xaddd",
ASG MINUS, "Xsubf", "Xsubd",
ASG MUL, "Xmulf", "Xmuld",
ASG DIV, "Xdivf", "Xdivd",
UNARY MINUS, "Xnegf", "Xnegd",
EQ, "Xcmpf", "Xcmpd",
NE, "Xcmpf", "Xcmpd",
LE, "Xcmpf", "Xcmpd",
LT, "Xcmpf", "Xcmpd",
GE, "Xcmpf", "Xcmpd",
GT, "Xcmpf", "Xcmpd",
SCONV, "Xcvtfl", "Xcvtdl",
SCONV, "Xcvtfu", "Xcvtdu",
SCONV, "Xcvtlf", "Xcvtld",
SCONV, "Xcvtuf", "Xcvtud",
0
};
hardops(p) register NODE *p; {
/* change hard to do operators into function calls. */
register NODE *q;
register struct functbl *f;
register o;
register TWORD t, t1, t2;
o = p->in.op;
for( f=opfunc; f->fop; f++ ) {
if( o==f->fop ) goto convert;
}
return;
convert:
t = p->in.type;
t1 = p->in.left->in.type;
if( t!=FLOAT && t!=DOUBLE && t1!=FLOAT && t1!=DOUBLE ) return;
if( o == SCONV ) {
if( t == FLOAT || t == DOUBLE ) {
if( t1 == FLOAT || t1 == DOUBLE )
return;
f += 2;
if(t1 == UNSIGNED)
f++;
} else {
if( t1 != FLOAT && t1 != DOUBLE )
return;
if(t == UNSIGNED)
f++;
}
}
/* need to rewrite tree for ASG OP */
/* must change ASG OP to a simple OP */
else if( asgop( o ) ) {
q = talloc();
q->in.op = NOASG ( o );
q->in.rall = NOPREF;
q->in.type = p->in.type;
q->in.left = tcopy(p->in.left);
q->in.right = p->in.right;
p->in.op = ASSIGN;
p->in.right = q;
zappost(q->in.left); /* remove post-INCR(DECR) from new node */
fixpre(q->in.left); /* change pre-INCR(DECR) to +/- */
p = q;
}
/* turn logicals to compare 0 */
else if( logop( o ) ) {
ncopy(q = talloc(), p);
p->in.left = q;
p->in.right = q = talloc();
q->in.op = ICON;
q->in.type = INT;
#ifndef FLEXNAMES
q->in.name[0] = '\0';
#else
q->in.name = "";
#endif
q->tn.lval = 0;
q->tn.rval = 0;
p = p->in.left;
}
/* build comma op for args to function */
t1 = p->in.left->in.type;
t2 = 0;
if ( optype(p->in.op) == BITYPE) {
q = talloc();
q->in.op = CM;
q->in.rall = NOPREF;
q->in.type = INT;
q->in.left = p->in.left;
q->in.right = p->in.right;
t2 = p->in.right->in.type;
} else
q = p->in.left;
p->in.op = CALL;
p->in.right = q;
/* put function name in left node of call */
p->in.left = q = talloc();
q->in.op = ICON;
q->in.rall = NOPREF;
q->in.type = INCREF( FTN + p->in.type );
if(t==FLOAT || o==SCONV && t1==FLOAT || logop(o) && t1==FLOAT && t2==FLOAT)
#ifndef FLEXNAMES
strcpy( q->in.name, f->funcf );
#else
q->in.name = f->funcf;
#endif
else
#ifndef FLEXNAMES
strcpy( q->in.name, f->funcd );
#else
q->in.name = f->funcd;
#endif
q->tn.lval = 0;
q->tn.rval = 0;
}
zappost(p) NODE *p; {
/* look for ++ and -- operators and remove them */
register o, ty;
register NODE *q;
o = p->in.op;
ty = optype( o );
switch( o ){
case INCR:
case DECR:
q = p->in.left;
p->in.right->in.op = FREE; /* zap constant */
ncopy( p, q );
q->in.op = FREE;
return;
}
if( ty == BITYPE ) zappost( p->in.right );
if( ty != LTYPE ) zappost( p->in.left );
}
fixpre(p) NODE *p; {
register o, ty;
o = p->in.op;
ty = optype( o );
switch( o ){
case ASG PLUS:
p->in.op = PLUS;
break;
case ASG MINUS:
p->in.op = MINUS;
break;
}
if( ty == BITYPE ) fixpre( p->in.right );
if( ty != LTYPE ) fixpre( p->in.left );
}
myreader(p) register NODE *p; {
walkf( p, hardops ); /* convert ops to function calls */
canon( p ); /* expands r-vals for fileds */
walkf( p, optim2 );
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.