1 /***** spin: flow.c *****/
4 * This file is part of the public release of Spin. It is subject to the
5 * terms in the LICENSE file that is included in this source directory.
6 * Tool documentation is available at http://spinroot.com
13 extern int nr_errs, lineno, verbose, in_for, old_scope_rules, s_trail;
14 extern short has_unless, has_badelse, has_xu;
15 extern char CurScope[MAXSCOPESZ];
18 Label *labtab = (Label *) 0;
19 int Unique = 0, Elcnt = 0, DstepStart = -1;
20 int initialization_ok = 1;
23 static Lbreak *breakstack = (Lbreak *) 0;
24 static Lextok *innermost;
25 static SeqList *cur_s = (SeqList *) 0;
26 static int break_id=0;
28 static Element *if_seq(Lextok *);
29 static Element *new_el(Lextok *);
30 static Element *unless_seq(Lextok *);
31 static void add_el(Element *, Sequence *);
32 static void attach_escape(Sequence *, Sequence *);
33 static void mov_lab(Symbol *, Element *, Element *);
34 static void walk_atomic(Element *, Element *, int);
39 Sequence *s = (Sequence *) emalloc(sizeof(Sequence));
42 t = seqlist(s, cur_s);
46 initialization_ok = 1;
48 { initialization_ok = 0;
65 Rjumpslocal(Element *q, Element *stop)
69 /* allow no jumps out of a d_step sequence */
70 for (f = q; f && f != stop; f = f->nxt)
71 { if (f && f->n && f->n->ntyp == GOTO)
72 { lb = get_lab(f->n, 0);
73 if (!lb || lb->Seqno < DstepStart)
78 for (h = f->sub; h; h = h->nxt)
79 { if (!Rjumpslocal(h->this->frst, h->this->last))
87 cross_dsteps(Lextok *a, Lextok *b)
90 && a->indstep != b->indstep)
94 fatal("jump into d_step sequence", (char *) 0);
101 return (n->ntyp == PRINT
105 && n->lft->ntyp == CONST
106 && n->lft->val == 1));
110 check_sequence(Sequence *s)
111 { Element *e, *le = ZE;
115 for (e = s->frst; e; le = e, e = e->nxt)
117 if (is_skip(n) && !has_lab(e, 0))
121 && n->ntyp != PRINTM)
123 printf("spin: %s:%d, redundant skip\n",
128 { e->status |= DONE; /* not unreachable */
129 le->nxt = e->nxt; /* remove it */
139 prune_opts(Lextok *n)
141 extern Symbol *context;
142 extern char *claimproc;
145 || (context && claimproc && strcmp(context->name, claimproc) == 0))
148 for (l = n->sl; l; l = l->nxt) /* find sequences of unlabeled skips */
149 check_sequence(l->this);
153 close_seq(int nottop)
154 { Sequence *s = cur_s->this;
157 if (nottop == 0) /* end of proctype body */
158 { initialization_ok = 1;
161 if (nottop > 0 && s->frst && (z = has_lab(s->frst, 0)))
162 { printf("error: (%s:%d) label %s placed incorrectly\n",
163 (s->frst->n)?s->frst->n->fn->name:"-",
164 (s->frst->n)?s->frst->n->ln:0,
168 printf("=====> stmnt unless Label: stmnt\n");
169 printf("sorry, cannot jump to the guard of an\n");
170 printf("escape (it is not a unique state)\n");
173 printf("=====> instead of ");
174 printf("\"Label: stmnt unless stmnt\"\n");
175 printf("=====> always use ");
176 printf("\"Label: { stmnt unless stmnt }\"\n");
179 printf("=====> instead of ");
180 printf("\"atomic { Label: statement ... }\"\n");
181 printf("=====> always use ");
182 printf("\"Label: atomic { statement ... }\"\n");
185 printf("=====> instead of ");
186 printf("\"d_step { Label: statement ... }\"\n");
187 printf("=====> always use ");
188 printf("\"Label: d_step { statement ... }\"\n");
191 printf("=====> instead of ");
192 printf("\"{ Label: statement ... }\"\n");
193 printf("=====> always use ");
194 printf("\"Label: { statement ... }\"\n");
197 printf("=====> instead of\n");
198 printf(" do (or if)\n");
200 printf(" :: Label: statement\n");
201 printf(" od (of fi)\n");
202 printf("=====> use\n");
203 printf("Label: do (or if)\n");
205 printf(" :: statement\n");
206 printf(" od (or fi)\n");
209 printf("cannot happen - labels\n");
217 && !Rjumpslocal(s->frst, s->last))
218 fatal("non_local jump in d_step sequence", (char *) 0);
224 fatal("sequence must have at least one statement", (char *) 0);
229 do_unless(Lextok *No, Lextok *Es)
231 Lextok *Re = nn(ZN, UNLESS, ZN, ZN);
237 if (Es->ntyp == NON_ATOMIC)
240 { open_seq(0); add_seq(Es);
241 Sl = seqlist(close_seq(1), 0);
244 if (No->ntyp == NON_ATOMIC)
247 } else if (No->ntyp == ':'
248 && (No->lft->ntyp == NON_ATOMIC
249 || No->lft->ntyp == ATOMIC
250 || No->lft->ntyp == D_STEP))
252 int tok = No->lft->ntyp;
254 No->lft->sl->nxt = Sl;
255 Re->sl = No->lft->sl;
257 open_seq(0); add_seq(Re);
258 Re = nn(ZN, tok, ZN, ZN);
259 Re->sl = seqlist(close_seq(7), 0);
263 Re = nn(No, ':', Re, ZN); /* lift label */
268 { open_seq(0); add_seq(No);
269 Sl = seqlist(close_seq(2), Sl);
277 seqlist(Sequence *s, SeqList *r)
278 { SeqList *t = (SeqList *) emalloc(sizeof(SeqList));
290 { if (n->ntyp == IF || n->ntyp == DO)
292 if (n->ntyp == UNLESS)
293 return unless_seq(n);
295 m = (Element *) emalloc(sizeof(Element));
299 m->Nxt = Al_El; Al_El = m;
304 has_chanref(Lextok *n)
313 case FULL: case NFULL:
314 case EMPTY: case NEMPTY:
319 if (has_chanref(n->lft))
322 return has_chanref(n->rgt);
326 loose_ends(void) /* properly tie-up ends of sub-sequences */
329 for (e = Al_El; e; e = e->Nxt)
333 switch (e->n->ntyp) {
338 while (f && f->n->ntyp == '.')
340 if (0) printf("link %d, {%d .. %d} -> %d (ntyp=%d) was %d\n",
342 e->n->sl->this->frst->seqno,
343 e->n->sl->this->last->seqno,
344 f?f->seqno:-1, f?f->n->ntyp:-1,
345 e->n->sl->this->last->nxt?e->n->sl->this->last->nxt->seqno:-1);
346 if (!e->n->sl->this->last->nxt)
347 e->n->sl->this->last->nxt = f;
349 { if (e->n->sl->this->last->nxt->n->ntyp != GOTO)
350 { if (!f || e->n->sl->this->last->nxt->seqno != f->seqno)
351 non_fatal("unexpected: loose ends", (char *)0);
353 e->n->sl->this->last = e->n->sl->this->last->nxt;
355 * fix_dest can push a goto into the nxt position
356 * in that case the goto wins and f is not needed
357 * but the last fields needs adjusting
368 fatal("cannot happen, breakstack", (char *) 0);
370 breakstack = breakstack->nxt; /* pop stack */
373 static Lbreak *ob = (Lbreak *) 0;
393 Element *e = new_el(ZN);
394 Element *t = new_el(nn(ZN,'.',ZN,ZN)); /* target */
395 SeqList *z, *prev_z = (SeqList *) 0;
396 SeqList *move_else = (SeqList *) 0; /* to end of optionlist */
399 for (z = s; z; z = z->nxt)
400 { if (!z->this->frst)
402 if (z->this->frst->n->ntyp == ELSE)
404 fatal("duplicate `else'", (char *) 0);
405 if (z->nxt) /* is not already at the end */
408 prev_z->nxt = z->nxt;
414 ref_chans |= has_chanref(z->this->frst->n);
418 { move_else->nxt = (SeqList *) 0;
419 /* if there is no prev, then else was at the end */
420 if (!prev_z) fatal("cannot happen - if_seq", (char *) 0);
421 prev_z->nxt = move_else;
426 && prev_z->this->frst->n->ntyp == ELSE)
427 { prev_z->this->frst->n->val = 1;
430 { fatal("invalid use of 'else' combined with i/o and xr/xs assertions,",
433 { non_fatal("dubious use of 'else' combined with i/o,",
439 e->n = nn(n, tok, ZN, ZN);
440 e->n->sl = s; /* preserve as info only */
442 for (z = s; z; z = z->nxt)
443 add_el(t, z->this); /* append target */
445 { add_el(t, cur_s->this); /* target upfront */
446 t = new_el(nn(n, BREAK, ZN, ZN)); /* break target */
447 set_lab(break_dest(), t); /* new exit */
450 add_el(e, cur_s->this);
451 add_el(t, cur_s->this);
452 return e; /* destination node for label */
456 escape_el(Element *f, Sequence *e)
459 for (z = f->esc; z; z = z->nxt)
461 return; /* already there */
463 /* cover the lower-level escapes of this state */
464 for (z = f->esc; z; z = z->nxt)
465 attach_escape(z->this, e);
467 /* now attach escape to the state itself */
469 f->esc = seqlist(e, f->esc); /* in lifo order... */
471 printf("attach %d (", e->frst->Seqno);
472 comment(stdout, e->frst->n, 0);
473 printf(") to %d (", f->Seqno);
474 comment(stdout, f->n, 0);
477 switch (f->n->ntyp) {
479 attach_escape(f->sub->this, e);
483 for (z = f->sub; z; z = z->nxt)
484 attach_escape(z->this, e);
487 /* attach only to the guard stmnt */
488 escape_el(f->n->sl->this->frst, e);
492 /* attach to all stmnts */
493 attach_escape(f->n->sl->this, e);
499 attach_escape(Sequence *n, Sequence *e)
502 for (f = n->frst; f; f = f->nxt)
510 unless_seq(Lextok *n)
511 { SeqList *s = n->sl;
512 Element *e = new_el(ZN);
513 Element *t = new_el(nn(ZN,'.',ZN,ZN)); /* target */
516 e->n = nn(n, UNLESS, ZN, ZN);
517 e->n->sl = s; /* info only */
520 /* need 2 sequences: normal execution and escape */
521 if (!s || !s->nxt || s->nxt->nxt)
522 fatal("unexpected unless structure", (char *)0);
524 /* append the target state to both */
525 for (z = s; z; z = z->nxt)
528 /* attach escapes to all states in normal sequence */
529 attach_escape(s->this, s->nxt->this);
531 add_el(e, cur_s->this);
532 add_el(t, cur_s->this);
534 printf("unless element (%d,%d):\n", e->Seqno, t->Seqno);
535 for (z = s; z; z = z->nxt)
536 { Element *x; printf("\t%d,%d,%d :: ",
537 z->this->frst->Seqno,
538 z->this->extent->Seqno,
539 z->this->last->Seqno);
540 for (x = z->this->frst; x; x = x->nxt)
541 printf("(%d)", x->Seqno);
550 { Lextok *t = nn(ZN, CONST, ZN, ZN);
552 return new_el(nn(ZN, 'c', t, ZN));
556 add_el(Element *e, Sequence *s)
558 if (e->n->ntyp == GOTO)
559 { Symbol *z = has_lab(e, (1|2|4));
561 { Element *y; /* insert a skip */
563 mov_lab(z, e, y); /* inherit label */
567 printf("add_el %d after %d -- ",
568 e->Seqno, (s->last)?s->last->Seqno:-1);
569 comment(stdout, e->n, 0);
585 { Element *e = colons(n->lft);
600 if (innermost->ntyp != IF
601 && innermost->ntyp != DO
602 && innermost->ntyp != UNLESS)
603 add_el(e, cur_s->this);
607 set_lab(Symbol *s, Element *e)
608 { Label *l; extern Symbol *context;
609 int cur_uiid = is_inline();
613 for (l = labtab; l; l = l->nxt)
614 { if (strcmp(l->s->name, s->name) == 0
616 && (old_scope_rules || strcmp((const char *) s->bscp, (const char *) l->s->bscp) == 0)
617 && l->uiid == cur_uiid)
618 { non_fatal("label %s redeclared", s->name);
622 if (strncmp(s->name, "accept", 6) == 0
623 && strncmp(s->name, "accept_all", 10) != 0)
627 l = (Label *) emalloc(sizeof(Label));
637 get_labspec(Lextok *n)
638 { Symbol *s = n->sym;
639 Label *l, *anymatch = (Label *) 0;
642 * try to find a label with the same inline id (uiid)
643 * but if it doesn't exist, return any other match
644 * within the same scope
646 for (l = labtab; l; l = l->nxt)
647 { if (strcmp(l->s->name, s->name) == 0 /* labelname matches */
648 && s->context == l->s->context) /* same scope */
651 if (anymatch && n->uiid == anymatch->uiid)
652 { if (0) non_fatal("label %s re-declared", s->name);
655 { printf("Label %s uiid now::then %d :: %d bcsp %s :: %s\n",
656 s->name, n->uiid, l->uiid, s->bscp, l->s->bscp);
657 printf("get_labspec match on %s %s (bscp goto %s - label %s)\n",
658 s->name, s->context->name, s->bscp, l->s->bscp);
661 /* same block scope */
662 if (strcmp((const char *) s->bscp, (const char *) l->s->bscp) == 0)
663 { return l; /* definite match */
665 /* higher block scope */
666 ln = strlen((const char *) l->s->bscp);
667 if (strncmp((const char *) s->bscp, (const char *) l->s->bscp, ln) == 0)
668 { anymatch = l; /* possible match */
669 } else if (!anymatch)
670 { anymatch = l; /* somewhere else in same context */
673 return anymatch; /* return best match */
677 get_lab(Lextok *n, int md)
678 { Label *l = get_labspec(n);
680 if (l != (Label *) 0)
687 fatal("undefined label %s", n->sym->name);
693 has_lab(Element *e, int special)
696 for (l = labtab; l; l = l->nxt)
700 || ((special&1) && !strncmp(l->s->name, "accept", 6))
701 || ((special&2) && !strncmp(l->s->name, "end", 3))
702 || ((special&4) && !strncmp(l->s->name, "progress", 8)))
709 mov_lab(Symbol *z, Element *e, Element *y)
712 for (l = labtab; l; l = l->nxt)
721 fatal("cannot happen - mov_lab %s", z->name);
725 fix_dest(Symbol *c, Symbol *a) /* c:label name, a:proctype name */
726 { Label *l; extern Symbol *context;
729 printf("ref to label '%s' in proctype '%s', search:\n",
731 for (l = labtab; l; l = l->nxt)
732 printf(" %s in %s\n", l->s->name, l->c->name);
735 for (l = labtab; l; l = l->nxt)
736 { if (strcmp(c->name, l->s->name) == 0
737 && strcmp(a->name, l->c->name) == 0) /* ? */
741 { printf("spin: label '%s' (proctype %s)\n", c->name, a->name);
742 non_fatal("unknown label '%s'", c->name);
744 printf("spin: cannot remote ref a label inside the same proctype\n");
747 if (!l->e || !l->e->n)
748 fatal("fix_dest error (%s)", c->name);
749 if (l->e->n->ntyp == GOTO)
750 { Element *y = (Element *) emalloc(sizeof(Element));
751 int keep_ln = l->e->n->ln;
752 Symbol *keep_fn = l->e->n->fn;
754 /* insert skip - or target is optimized away */
755 y->n = l->e->n; /* copy of the goto */
756 y->seqno = find_maxel(a); /* unique seqno within proc */
758 y->Seqno = Unique++; y->Nxt = Al_El; Al_El = y;
760 /* turn the original element+seqno into a skip */
761 l->e->n = nn(ZN, 'c', nn(ZN, CONST, ZN, ZN), ZN);
762 l->e->n->ln = l->e->n->lft->ln = keep_ln;
763 l->e->n->fn = l->e->n->lft->fn = keep_fn;
764 l->e->n->lft->val = 1;
765 l->e->nxt = y; /* append the goto */
767 l->e->status |= CHECK2; /* treat as if global */
768 if (l->e->status & (ATOM | L_ATOM | D_ATOM))
769 { printf("spin: %s:%d, warning, reference to label ",
770 Fname->name, lineno);
771 printf("from inside atomic or d_step (%s)\n", c->name);
776 find_lab(Symbol *s, Symbol *c, int markit)
777 { Label *l, *pm = (Label *) 0, *apm = (Label *) 0;
780 /* generally called for remote references in never claims */
781 for (l = labtab; l; l = l->nxt)
783 if (strcmp(s->name, l->s->name) == 0
784 && strcmp(c->name, l->c->name) == 0)
785 { ln = strlen((const char *) l->s->bscp);
787 { printf("want '%s' in context '%s', scope ref '%s' - label '%s'\n",
788 s->name, c->name, s->bscp, l->s->bscp);
790 /* same or higher block scope */
791 if (strcmp((const char *) s->bscp, (const char *) l->s->bscp) == 0)
792 { pm = l; /* definite match */
795 if (strncmp((const char *) s->bscp, (const char *) l->s->bscp, ln) == 0)
796 { pm = l; /* possible match */
798 { apm = l; /* remote */
802 { pm->visible |= markit;
806 { apm->visible |= markit;
807 return apm->e->seqno;
808 } /* else printf("Not Found\n"); */
814 { Lbreak *r = (Lbreak *) emalloc(sizeof(Lbreak));
818 sprintf(buf, ":b%d", break_id++);
829 fatal("misplaced break statement", (char *)0);
830 return breakstack->l;
834 make_atomic(Sequence *s, int added)
837 walk_atomic(s->frst, s->last, added);
840 switch (f->n->ntyp) { /* is last step basic stmnt or sequence ? */
843 /* redo and search for the last step of that sequence */
844 make_atomic(f->n->sl->this, added);
848 /* escapes are folded into main sequence */
849 make_atomic(f->sub->this, added);
860 static int depth = 0;
861 void dump_sym(Symbol *, char *);
864 dump_lex(Lextok *t, char *s)
869 for (i = 0; i < depth; i++)
872 if (t->ntyp == NAME) printf(" %s ", t->sym->name);
873 if (t->ntyp == CONST) printf(" %d ", t->val);
874 if (t->ntyp == STRUCT)
875 { dump_sym(t->sym, "\n:Z:");
878 { dump_lex(t->lft, "\nL");
881 { dump_lex(t->rgt, "\nR");
886 dump_sym(Symbol *z, char *s)
891 for (i = 0; i < depth; i++)
895 { if (z->ini && z->ini->rgt && z->ini->rgt->sym)
896 { /* dump_sym(z->ini->rgt->sym, "\n:I:"); -- could also be longer list */
898 || !z->ini->rgt->sym)
899 fatal("chan %s in for should have only one field (a typedef)", z->name);
900 printf(" -- %s %p -- ", z->ini->rgt->sym->name, z->ini->rgt->sym);
902 } else if (z->type == STRUCT)
904 printf(" == %s %p == ", z->Snm->name, z->Snm);
907 dump_lex(z->Slst, "\n:X:");
909 dump_lex(z->ini, "\n:I:");
918 match_struct(Symbol *s, Symbol *t)
925 { fatal("chan %s in for should have only one field (a typedef)", t?t->name:"--");
927 /* we already know that s is a STRUCT */
929 { printf("index type %s %p ==\n", s->Snm->name, s->Snm);
930 printf("chan type %s %p --\n\n", t->ini->rgt->sym->name, t->ini->rgt->sym);
933 return (s->Snm == t->ini->rgt->sym);
937 valid_name(Lextok *a3, Lextok *a5, Lextok *a8, char *tp)
939 if (a3->ntyp != NAME)
940 { fatal("%s ( .name : from .. to ) { ... }", tp);
942 if (a3->sym->type == CHAN
943 || a3->sym->type == STRUCT
944 || a3->sym->isarray != 0)
945 { fatal("bad index in for-construct %s", a3->sym->name);
947 if (a5->ntyp == CONST && a8->ntyp == CONST && a5->val > a8->val)
948 { non_fatal("start value for %s exceeds end-value", a3->sym->name);
953 for_setup(Lextok *a3, Lextok *a5, Lextok *a8)
954 { /* for ( a3 : a5 .. a8 ) */
956 valid_name(a3, a5, a8, "for");
957 /* a5->ntyp = a8->ntyp = CONST; */
958 add_seq(nn(a3, ASGN, a3, a5)); /* start value */
960 add_seq(nn(ZN, 'c', nn(a3, LE, a3, a8), ZN)); /* condition */
964 for_index(Lextok *a3, Lextok *a5)
965 { Lextok *z0, *z1, *z2, *z3;
967 char tmp_nm[MAXSCOPESZ+16];
968 /* for ( a3 in a5 ) { ... } */
970 if (a3->ntyp != NAME)
971 { fatal("for ( .name in name ) { ... }", (char *) 0);
974 if (a5->ntyp != NAME)
975 { fatal("for ( %s in .name ) { ... }", a3->sym->name);
978 if (a3->sym->type == STRUCT)
979 { if (a5->sym->type != CHAN)
980 { fatal("for ( %s in .channel_name ) { ... }",
986 || z0->rgt->ntyp != STRUCT
987 || z0->rgt->rgt != NULL)
988 { fatal("bad channel type %s in for", a5->sym->name);
991 if (!match_struct(a3->sym, a5->sym))
992 { fatal("type of %s does not match chan", a3->sym->name);
995 z1 = nn(ZN, CONST, ZN, ZN); z1->val = 0;
996 z2 = nn(a5, LEN, a5, ZN);
998 sprintf(tmp_nm, "_f0r_t3mp%s", CurScope); /* make sure it's unique */
999 tmp_cnt = lookup(tmp_nm);
1000 if (z0->val > 255) /* check nr of slots, i.e. max length */
1001 { tmp_cnt->type = SHORT; /* should be rare */
1003 { tmp_cnt->type = BYTE;
1005 z3 = nn(ZN, NAME, ZN, ZN);
1008 add_seq(nn(z3, ASGN, z3, z1)); /* start value 0 */
1012 add_seq(nn(ZN, 'c', nn(z3, LT, z3, z2), ZN)); /* condition */
1014 /* retrieve message from the right slot -- for now: rotate contents */
1016 add_seq(nn(a5, 'r', a5, expand(a3, 1))); /* receive */
1017 add_seq(nn(a5, 's', a5, expand(a3, 1))); /* put back in to rotate */
1021 { if (a5->sym->isarray == 0
1022 || a5->sym->nel <= 0)
1023 { fatal("bad arrayname %s", a5->sym->name);
1025 z1 = nn(ZN, CONST, ZN, ZN); z1->val = 0;
1026 z2 = nn(ZN, CONST, ZN, ZN); z2->val = a5->sym->nel - 1;
1027 for_setup(a3, z1, z2);
1033 for_body(Lextok *a3, int with_else)
1034 { Lextok *t1, *t2, *t0, *rv;
1036 rv = nn(ZN, CONST, ZN, ZN); rv->val = 1;
1037 rv = nn(ZN, '+', a3, rv);
1038 rv = nn(a3, ASGN, a3, rv);
1039 add_seq(rv); /* initial increment */
1041 /* completed loop body, main sequence */
1042 t1 = nn(ZN, 0, ZN, ZN);
1043 t1->sq = close_seq(8);
1045 open_seq(0); /* add else -> break sequence */
1047 { add_seq(nn(ZN, ELSE, ZN, ZN));
1049 t2 = nn(ZN, GOTO, ZN, ZN);
1050 t2->sym = break_dest();
1052 t2 = nn(ZN, 0, ZN, ZN);
1053 t2->sq = close_seq(9);
1055 t0 = nn(ZN, 0, ZN, ZN);
1056 t0->sl = seqlist(t2->sq, seqlist(t1->sq, 0));
1058 rv = nn(ZN, DO, ZN, ZN);
1065 sel_index(Lextok *a3, Lextok *a5, Lextok *a7)
1066 { /* select ( a3 : a5 .. a7 ) */
1068 valid_name(a3, a5, a7, "select");
1069 /* a5->ntyp = a7->ntyp = CONST; */
1071 add_seq(nn(a3, ASGN, a3, a5)); /* start value */
1073 add_seq(nn(ZN, 'c', nn(a3, LT, a3, a7), ZN)); /* condition */
1075 pushbreak(); /* new 6.2.1 */
1076 return for_body(a3, 0); /* no else, just a non-deterministic break */
1080 walk_atomic(Element *a, Element *b, int added)
1081 { Element *f; Symbol *ofn; int oln;
1086 for (f = a; ; f = f->nxt)
1087 { f->status |= (ATOM|added);
1088 switch (f->n->ntyp) {
1091 printf("spin: %s:%d, warning, atomic inside %s (ignored)\n",
1092 f->n->fn->name, f->n->ln, (added)?"d_step":"atomic");
1096 { if (added) goto mknonat;
1099 printf("spin: %s:%d, warning, d_step inside ",
1100 f->n->fn->name, f->n->ln);
1102 { printf("d_step (ignored)\n");
1108 mknonat: f->n->ntyp = NON_ATOMIC; /* can jump here */
1110 walk_atomic(h->this->frst, h->this->last, added);
1114 { printf("spin: error, %s:%d, unless in d_step (ignored)\n",
1115 f->n->fn->name, f->n->ln);
1118 for (h = f->sub; h; h = h->nxt)
1119 walk_atomic(h->this->frst, h->this->last, added);
1131 for (l = labtab; l; l = l->nxt)
1132 if (l->c != 0 && l->s->name[0] != ':')
1133 { printf("label %s %d ",
1134 l->s->name, l->e->seqno);
1136 printf("<%s>", l->c->name);
1138 printf("<%s i%d>", l->c->name, l->uiid);
1139 if (!old_scope_rules)
1140 { printf("\t{scope %s}", l->s->bscp);