register struct tnode
*t
, *t1
;
if ((t
=at
)==0 || t
->op
==0)
if ((t1
= isconstant(t
)) && (t1
->value
>=0 || t1
->type
==UNSIGN
))
if ((t1
=t
->tr1
)->type
==UNSIGN
&& opdope
[t1
->op
]&LEAF
)
if ((opdope
[t
->op
] & LEAF
) != 0) {
if (t
->type
==CHAR
|| t
->type
==FLOAT
)
register struct tnode
*p
;
printf("$%o", flag
>10? p
->lvalue
.intx
[1]:p
->lvalue
.intx
[0]);
printf("L%d", (p
->value
>0? p
->value
: -p
->value
));
printf("(r%d)", p
->regno
);
error("Compiler error: pname");
if (p
->op
==NAME
&& p
->class==REG
)
printf("(r%d)%c", p
->nloc
, flag
==1?0:'+');
printf("%c(r%d)", flag
==2?0:'-', p
->nloc
);
error("pname called illegally");
error("Illegal use of register");
register struct tnode
*p
;
if (p
->class==SOFFS
|| p
->class==STATIC
)
printf("%.8s", &(p
->nloc
));
register struct tnode
*p
;
if (d
<20 && p
->type
==CHAR
) {
register struct tnode
*p
, *p1
;
if (p1
->op
==NAME
||p1
->op
==CON
||p1
->op
==AUTOI
||p1
->op
==AUTOD
)
return(p
->degree
<= nrleft
? 20: 24);
register struct tnode
*p
;
if (st
==0) /* word, byte */
return(at
!=CHAR
&& at
!=INT
&& at
!=UNSIGN
&& at
<PTR
);
return(at
!=INT
&& at
!=UNSIGN
&& at
<PTR
);
if ((at
&(~(TYPE
+XTYPE
))) != 0)
if (st
==FLOAT
&& at
==DOUBLE
)
if (p
->op
==NAME
&& p
->class==REG
&& op
==ASSIGN
&& st
==CHAR
)
register struct instab
*insp
;
for (insp
=itable
; insp
->op
!= 0; insp
++) {
ip
= c
? insp
->str2
: insp
->str1
;
error("No match' for op %d", op
);
register struct tnode
*p
;
if (p
->type
==LONG
+PTR
) /* avoid *x(r); *x+2(r) */
if (op
==CON
|| op
==AMPER
)
register struct tnode
*t
;
if ((opdope
[t
->op
]&RELAT
)!=0)
if (t
->type
==FLOAT
|| t
->type
==DOUBLE
) {
if (opdope
[t
->op
]&RELAT
) {
* Strings for switch code.
* If the unsigned casts below won't compile,
* try using the calls to lrem and ldiv.
pswitch(afp
, alp
, deflab
)
int ncase
, i
, j
, tabs
, worst
, best
, range
;
register struct swtab
*swp
, *fp
, *lp
;
printf("jbr L%d\n", deflab
);
range
= lp
->swval
- fp
->swval
;
if (range
>0 && range
<= 3*ncase
) {
printf("sub $%o,r0\n", fp
->swval
);
printf(dirsw
, range
, deflab
, isn
, isn
);
for (i
=fp
->swval
; ; i
++) {
printf("L%d\n", fp
->swlab
);
for (fp
= afp
; fp
<=lp
; fp
++)
breq(fp
->swval
, fp
->swlab
);
printf("jbr L%d\n", deflab
);
poctab
= getblk(((ncase
+2)/2) * sizeof(*poctab
));
for (i
=ncase
/4; i
<=ncase
/2; i
++) {
for (swp
=fp
; swp
<=lp
; swp
++)
/* lrem(0, swp->swval, i) */
poctab
[(unsigned)swp
->swval
%i
]++;
printf(hashsw
, tabs
, i
, i
);
for (swp
=fp
; swp
<=lp
; swp
++) {
/* lrem(0, swp->swval, tabs) */
if ((unsigned)swp
->swval
%tabs
== i
) {
/* ldiv(0, swp->swval, tabs) */
breq((unsigned)swp
->swval
/tabs
, swp
->swlab
);
printf("jbr L%d\n", deflab
);
printf("cmp r0,$%o\n", v
);
register struct swtab
*cp
, *fp
, *lp
;
for (cp
=fp
; cp
<lp
; cp
++) {
if (cp
->swval
== cp
[1].swval
) {
error("Duplicate case (%d)", cp
->swval
);
if (cp
->swval
> cp
[1].swval
) {
register struct tnode
*tree
;
if (!isfloat(tree
) && tree
->tr2
->op
==CON
) {
register struct tnode
*tree
;
for (i
=0; (d
=>>1)!=0; i
++);
tree
->tr2
->value
= (1<<i
)-1;
tree
->tr2
->value
= (1<<i
)-1;
cbranch(atree
, albl
, cond
, areg
)
register struct tnode
*tree
;
cbranch(tree
->tr1
, l1
=isn
++, 0, reg
);
cbranch(tree
->tr2
, lbl
, 1, reg
);
cbranch(tree
->tr1
, lbl
, 0, reg
);
cbranch(tree
->tr2
, lbl
, 0, reg
);
cbranch(tree
->tr1
, lbl
, 1, reg
);
cbranch(tree
->tr2
, lbl
, 1, reg
);
cbranch(tree
->tr1
, l1
=isn
++, 1, reg
);
cbranch(tree
->tr2
, lbl
, 0, reg
);
cbranch(tree
->tr1
, lbl
, !cond
, reg
);
rcexpr(tree
->tr1
, efftab
, reg
);
&& tree
->tr1
->op
==ITOL
&& tree
->tr2
->op
==ITOL
) {
tree
->tr1
= tree
->tr1
->tr1
;
tree
->tr2
= tree
->tr2
->tr1
;
if (op
>=LESSEQ
&& op
<=GREAT
&& (tree
->tr1
->type
==UNSIGN
|| tree
->tr2
->type
==UNSIGN
))
tree
->op
= op
= op
+LESSEQP
-LESSEQ
;
|| opdope
[op
]&RELAT
&&tree
->tr1
->type
==LONG
) {
longrel(tree
, lbl
, cond
, reg
);
rcexpr(tree
, cctab
, reg
);
if ((opdope
[op
]&RELAT
)==0)
if ((l1
==CON
|| l1
==SFCON
) && tree
->tr2
->value
==0)
op
=+ 200; /* special for ptr tests */
longrel(atree
, lbl
, cond
, reg
)
register struct tnode
*tree
;
reorder(&atree
, cctab
, reg
);
if (opdope
[tree
->op
]&RELAT
) {
xzero
= !isrel
|| tree
->tr2
->op
==ITOL
&& tree
->tr2
->tr1
->op
==CON
&& tree
->tr2
->tr1
->value
==0;
tree
->tr2
= optim(tnode(COMPL
, LONG
, tree
->tr2
));
if (cexpr(tree
, cctab
, reg
) < 0) {
reg
= rcexpr(tree
, regtab
, reg
);
printf("ashc $0,r%d\n", reg
);
* Tables for finding out how best to do long comparisons.
* First dimen is whether or not the comparison is with 0.
* Second is which test: e.g. a>b->
* Note some tests may not be needed.
0, NEQUAL
, LESS
, LESS
, GREAT
, GREAT
,
NEQUAL
, 0, GREAT
, GREAT
, LESS
, LESS
,
EQUAL
, NEQUAL
, LESSEQP
,LESSP
, GREATQP
,GREATP
,
0, NEQUAL
, LESS
, LESS
, GREATEQ
,GREAT
,
NEQUAL
, 0, GREAT
, 0, 0, LESS
,
EQUAL
, NEQUAL
, EQUAL
, 0, 0, NEQUAL
,
if (bno
= lrtab
[xzero
][0][op
-EQUAL
])
if (bno
= lrtab
[xzero
][1][op
-EQUAL
]) {
if (lrtab
[xzero
][2][op
-EQUAL
]==0)
branch(xlab1
, lrtab
[xzero
][2][op
-EQUAL
], 0);
printf("cmp (sp)+,(sp)+\n");
printf("add $%o,sp\n", a
);
error(s
, p1
, p2
, p3
, p4
, p5
, p6
)
fprintf(stderr
, "%d: ", line
);
fprintf(stderr
, s
, p1
, p2
, p3
, p4
, p5
, p6
);
* Read in an intermediate file.
struct tnode
*expstack
[STKS
];
register struct tnode
**sp
;
int lbl
, cond
, lbl2
, lbl3
;
if (sp
>= &expstack
[STKS
])
error("Stack overflow botch");
if ((op
&0177400) != 0177000) {
error("Intermediate file error");
printf(".globl%s%.8s\n", s
[0]?" ":"", s
);
printf(".comm %.8s,%o\n", t
, geti());
printf(".=.+%o\n", (t
=geti()));
printf("sub $%o,sp\n", t
);
printf("mov $L%d,r0\njsr pc,mcount\n", t
);
printf(".bss\nL%d:.=.+2\n.text\n", t
);
printf("~%s=L%d\n", t
+1, geti());
printf("~%s=%o\n", t
+1, geti());
printf("~%s=r%d\n", t
+1, geti());
while(swp
=getblk(sizeof(*swp
)), swp
->swlab
= geti())
pswitch(funcbase
, swp
, t
);
case C3BRANCH
: /* for fortran [sic] */
if (sp
!= &expstack
[1]) {
error("Expression input botch");
cbranch(*sp
, lbl
, cond
, 0);
rcexpr(tnode(RFORCE
, (*sp
)->type
, *sp
), efftab
, 0);
printf("jgt L%d\n", lbl3
);
printf("jlt L%d\njbr L%d\n", lbl
, lbl2
);
np
= getblk(sizeof(*xnp
));
np
= getblk(sizeof(*np
));
*sp
++ = tconst(geti(), t
);
geti(); /* ignore type, assume long */
if (t
==0 && op
>=0 || t
== -1 && op
<0) {
*sp
++ = tnode(ITOL
, LONG
, tconst(op
, INT
));
lp
= getblk(sizeof(*lp
));
lp
->lvalue
= ((long)t
<<16) + (unsigned)op
; /* nonportable */
fp
= getblk(sizeof(*fp
));
fp
->fvalue
= atof(numbuf
);
*sp
= tnode(FSEL
, geti(), *--sp
, NULL
);
(*sp
++)->tr2
= tnode(COMMA
, INT
, tconst(geti(), INT
), tconst(t
, INT
));
sap
= getblk(sizeof(*sap
));
*sp
++ = tnode(0, 0, NULL
, NULL
);
printf("%.8s:\n~~%s:\n", t
, t
+1);
error("Binary expression botch");
*sp
++ = tnode(op
, geti(), *--sp
, t
);
sp
[-1] = tnode(op
, geti(), sp
[-1]);
register struct tnode
*tp
;
nwords
= atp
->mask
/sizeof(int);
if (tp
->op
==RFORCE
) { /* function return */
printf(".bss\nL%d:.=.+%o\n.text\n", sfuncr
.nloc
, nwords
*sizeof(int));
atp
->tr1
= tnode(ASSIGN
, STRUCT
, &sfuncr
, tp
->tr1
);
printf("mov $L%d,r0\n", sfuncr
.nloc
);
error("Illegal structure operation");
tp
->tr2
= strfunc(tp
->tr2
);
else if (nwords
==sizeof(int))
if (tp
->tr1
->op
!=NAME
&& tp
->tr1
->op
!=STAR
|| tp
->tr2
->op
!=NAME
&& tp
->tr2
->op
!=STAR
) {
error("unimplemented structure assignment");
tp
->tr1
= tnode(AMPER
, STRUCT
+PTR
, tp
->tr1
);
tp
->tr2
= tnode(AMPER
, STRUCT
+PTR
, tp
->tr2
);
printf("mov (r1)+,(r0)+\n");
printf("mov r2,-(sp)\n");
printf("mov $%o,r2\n", nwords
);
printf("L%d:mov (r1)+,(r0)+\ndec\tr2\njne\tL%d\n", isn
, isn
);
printf("mov (sp)+,r2\n");
register struct tnode
*p
;
* Reduce the degree-of-reference by one.
* e.g. turn "ptr-to-int" into "int".
error("Illegal indirection");
return((t
>>TYLEN
) & ~TYPE
| t
&TYPE
);
* Increase the degree of reference by
* one; e.g. turn "int" to "ptr-to-int".
return(((t
&~TYPE
)<<TYLEN
) | (t
&TYPE
) | PTR
);