8 #define _va_start(argp, arg) va_start(argp, arg)
11 #define _va_start(argp, arg) va_start(argp)
14 #include "c1.h" /* rcexpr0() one-pass version */
17 * Reduce the degree-of-reference by one.
18 * e.g. turn "ptr-to-int" into "int".
20 int decref0(t) register int t; {
21 if ((t & ~TYPE) == 0) {
22 error0("Illegal indirection");
25 return((t>>TYLEN) & ~TYPE | t&TYPE);
29 * Increase the degree of reference by
30 * one; e.g. turn "int" to "ptr-to-int".
32 int incref0(t) register int t; {
33 return(((t&~TYPE)<<TYLEN) | (t&TYPE) | PTR);
37 * Make a tree that causes a branch to lbl
38 * if the tree's value is non-zero together with the cond.
40 void cbranch0(t, lbl, cond) struct node *t; int lbl; int cond; {
41 #if 1 /* one-pass version */
46 fprintf(stderr, "a seek %ld\n", outloc);
48 fseek(/*stdout*/temp_fp[temp_fi], outloc, 0);
53 if (regpanic==0 && panicposs)
55 outloc = ftell(/*stdout*/temp_fp[temp_fi]);
56 fprintf(stderr, "a tell %ld\n", outloc);
57 cbranch1(t, lbl, cond, 0);
58 fprintf(stderr, "a done\n");
61 cbranch1(t, lbl, cond, 0);
64 outcode("BNNN", CBRANCH, lbl, cond, line);
71 void rcexpr0(tp) register struct node *tp; {
72 #if 1 /* one-pass version */
76 * Special optimization
78 if (tp->n_op==INIT && ((struct tnode *)tp)->tn_tr1->n_op==CON) {
79 #define ttp ((struct tnode *)tp)
80 if (ttp->tn_type==CHAR || ttp->tn_type==UNCHAR) {
81 outcode("B1N0", BDATA, ((struct cnode *)ttp->tn_tr1)->cn_value);
83 } else if (ttp->tn_type==INT || ttp->tn_type==UNSIGN) {
84 outcode("BN", SINIT, ((struct cnode *)ttp->tn_tr1)->cn_value);
89 #if 1 /* one-pass version */
92 fprintf(stderr, "b seek %ld\n", outloc);
94 fseek(/*stdout*/temp_fp[temp_fi], outloc, 0);
99 if (regpanic==0 && panicposs)
101 outloc = ftell(/*stdout*/temp_fp[temp_fi]);
102 fprintf(stderr, "b tell %ld\n", outloc);
103 rcexpr1(tp, efftab, 0);
104 fprintf(stderr, "b done\n");
107 rcexpr1(tp, efftab, 0);
110 outcode("BN", EXPR, line);
115 void treeout(tp, isstruct) register struct node *tp; int isstruct; {
116 register struct nmlist *hp;
117 register int nextisstruct;
119 if (tp == NULL || tp->tn_op==NULLOP0) {
120 outcode("B", NULLOP);
123 nextisstruct = tp->tn_type==STRUCT;
127 hp = (struct nmlist *)tp->tn_tr1;
128 if (hp->nl_class==TYPEDEF)
129 error0("Illegal use of type name");
131 if (hp->nl_class==EXTERN)
132 outcode("BNNS", NAME, EXTERN, tp->tn_type, hp->nl_name);
134 outcode("BNNN", NAME, hp->nl_class==0?STATIC:hp->nl_class, tp->tn_type, hp->nl_offset);
136 outcode("BNN", NAME, hp->nl_class==0?STATIC:hp->nl_class, tp->tn_type);
137 if (hp->nl_class==EXTERN)
138 outcode("S", hp->nl_name);
140 outcode("N", hp->nl_offset);
145 outcode("BNNN", tp->ln_op, tp->ln_type, (_UNSIGNED_INT)(tp->ln_lvalue>>16),
146 (_UNSIGNED_INT)tp->ln_lvalue);
150 outcode("BNN", tp->cn_op, tp->cn_type, tp->cn_value);
154 outcode("BNF", tp->fn_op, tp->fn_type, tp->f.cstr);
158 outcode("BNNN", NAME, STATIC, tp->tn_type, tp->tn_tr1);
162 treeout(tp->tn_tr1, nextisstruct);
163 outcode("BNNN", tp->tn_op, tp->tn_type,
164 ((struct FS *)tp->tn_tr2)->bitoffs, ((struct FS *)tp->tn_tr2)->flen);
168 error0("Illegal use of type");
172 treeout(tp->tn_tr1, 1);
173 outcode("BN", tp->tn_op, tp->tn_type);
178 treeout(tp->tn_tr1, 1);
179 treeout(tp->tn_tr2, 0);
180 outcode("BN", CALL, tp->tn_type);
184 treeout(tp->tn_tr1, nextisstruct);
185 if (opdope0[tp->tn_op]&BINARY)
186 treeout(tp->tn_tr2, nextisstruct);
187 outcode("BN", tp->tn_op, tp->tn_type);
190 if (nextisstruct && isstruct==0)
191 outcode("BNN", STRASG, STRUCT, tp->tn_strp->S.ssize);
198 void branch0(lab) int lab; {
199 outcode("BN", BRANCH, lab);
205 void label0(l) int l; {
206 outcode("BN", LABEL, l);
210 * ap is a tree node whose type
211 * is some kind of pointer; return the size of the object
212 * to which the pointer points.
214 int XXXlength(cs) struct node *cs; {
215 register int t, elsz;
222 while ((t&XTYPE) == ARRAY) {
224 n *= cs->n_subsp[nd++];
230 else switch(t&TYPE) {
233 error0("Illegal use of void object");
260 if ((elsz = cs->n_strp->S.ssize) == 0)
261 error0("Undefined structure");
264 error0("Compiler error0 (length)");
267 /*fprintf(stderr, "%d %d %d\n", (int)n, (int)elsz, (int)(n * elsz));*/
269 if (n >= (_UNSIGNED_INT)50000)
270 werror0("very large data structure");
273 int plength(p) register struct node *p; {
276 if (p==0 || ((t=p->n_type)&~TYPE) == 0) /* not a reference */
278 p->n_type = decref0(t);
285 * return the number of bytes in the object
286 * whose tree node is acs.
288 int length(cs) struct /*node*/type *cs; {
289 register int /*t,*/ elsz;
290 register struct type *t;
297 while ((t&XTYPE) == ARRAY) {
299 n *= cs->n_subsp[nd++];
302 for (t = cs; t->t_id == (REF | ARRAY); t = ((struct atype *)t)->at_reftype)
303 n *= ((struct atype *)t)->at_nelt;
304 if (/*(t&~TYPE)==FUNC*/t->t_id==(REF|FUNC))
308 else*/ switch(/*t&TYPE*/t->t_id) {
314 error0("Illegal use of void object");
341 if ((elsz = /*cs->n_strp->S.ssize*/((struct stype *)t)->st_ssize) == 0)
342 error0("Undefined structure");
345 error0("Compiler error (length)");
348 /*fprintf(stderr, "%d %d %d\n", (int)n, (int)elsz, (int)(n * elsz));*/
350 if (n >= (_UNSIGNED_INT)50000)
351 werror0("very large data structure");
356 * The number of bytes in an object, rounded up to a word.
358 int rlength(cs) struct /*node*/type *cs; {
359 return((length(cs)+ALIGN) & ~ALIGN);
363 * After an "if (...) goto", look to see if the transfer
364 * is to a simple label.
366 extern struct type gototype; /* dummy type distinguished by its address */
368 register struct nmlist *csp;
370 if ((peeksym=symbol())==NAME && nextchar()==';') {
372 if (csp->nl_blklev == 0)
374 if (csp->nl_class==0 && csp->/*nl_type==0*/nl_dtype==NULL) {
375 /* csp->nl_type = ARRAY;*/
376 csp->nl_dtype = &gototype;
377 csp->nl_flag |= FLABL;
378 if (csp->nl_offset==0)
379 csp->nl_offset = isn0++;
381 if ((csp->nl_class==0||csp->nl_class==STATIC)
382 && /*csp->nl_type==ARRAY*/csp->nl_dtype==&gototype) {
384 return(csp->nl_offset);
391 * Return the next non-white-space character
394 while (spnextchar()==' ')
400 * Return the next character, translating all white space
401 * to blank and handling line-ends.
408 if (c=='\t' || c=='\014') /* FF */
419 * is a break or continue legal?
421 void chconbrk(l) int l; {
423 error0("Break/continue error");
427 * The goto statement.
430 register struct node *np;
436 chkw(np = *--cp, -1);
437 rcexpr0((struct node *)block(JUMP, 0, (int *)NULL, (union str *)NULL, np, (struct node *)NULL));
442 * The return statement, which has to convert
443 * the returned object to the function's type.
446 if (nextchar() != ';') {
450 *cp++ = (struct node *)&funcblk;
453 cp[-1] = ((struct tnode *)cp[-1])->tn_tr2;
462 * Write a character on the error output.
466 * B: beginning of line; an operator
468 * S: a symbol (external)
474 void outcode(char *s, ...)
476 void outcode(s, va_alist) char *s; va_dcl
486 bufp = temp_fp[temp_fi];
493 for (;;) switch(*s++) {
495 ni = va_arg(ap, int);
501 ni = va_arg(ap, int);
507 np = va_arg(ap, char *);
512 np = va_arg(ap, char *);
518 fputc(*np++ & 0177, bufp);
536 error0("Write error on temp");
542 error0("Botch in outcode");
547 unsigned int hash(sp) register char *sp; {
548 register unsigned int h;