1219b2ee8SDavid du Colombier /***** spin: dstep.c *****/
2219b2ee8SDavid du Colombier
3*de2caf28SDavid du Colombier /*
4*de2caf28SDavid du Colombier * This file is part of the public release of Spin. It is subject to the
5*de2caf28SDavid du Colombier * terms in the LICENSE file that is included in this source directory.
6*de2caf28SDavid du Colombier * Tool documentation is available at http://spinroot.com
7*de2caf28SDavid du Colombier */
8219b2ee8SDavid du Colombier
9*de2caf28SDavid du Colombier #include <assert.h>
10219b2ee8SDavid du Colombier #include "spin.h"
11219b2ee8SDavid du Colombier #include "y.tab.h"
127dd7cddfSDavid du Colombier
1300d97012SDavid du Colombier #define MAXDSTEP 2048 /* was 512 */
14219b2ee8SDavid du Colombier
15*de2caf28SDavid du Colombier char *NextLab[64]; /* must match value in pangen2.c:41 */
16219b2ee8SDavid du Colombier int Level=0, GenCode=0, IsGuard=0, TestOnly=0;
17219b2ee8SDavid du Colombier
187dd7cddfSDavid du Colombier static int Tj=0, Jt=0, LastGoto=0;
197dd7cddfSDavid du Colombier static int Tojump[MAXDSTEP], Jumpto[MAXDSTEP], Special[MAXDSTEP];
207dd7cddfSDavid du Colombier static void putCode(FILE *, Element *, Element *, Element *, int);
217dd7cddfSDavid du Colombier
22*de2caf28SDavid du Colombier extern int Pid_nr, separate, OkBreak;
237dd7cddfSDavid du Colombier
247dd7cddfSDavid du Colombier static void
Sourced(int n,int special)25219b2ee8SDavid du Colombier Sourced(int n, int special)
26219b2ee8SDavid du Colombier { int i;
27219b2ee8SDavid du Colombier for (i = 0; i < Tj; i++)
28219b2ee8SDavid du Colombier if (Tojump[i] == n)
29219b2ee8SDavid du Colombier return;
307dd7cddfSDavid du Colombier if (Tj >= MAXDSTEP)
317dd7cddfSDavid du Colombier fatal("d_step sequence too long", (char *)0);
32219b2ee8SDavid du Colombier Special[Tj] = special;
33219b2ee8SDavid du Colombier Tojump[Tj++] = n;
34219b2ee8SDavid du Colombier }
35219b2ee8SDavid du Colombier
367dd7cddfSDavid du Colombier static void
Dested(int n)37219b2ee8SDavid du Colombier Dested(int n)
38219b2ee8SDavid du Colombier { int i;
39219b2ee8SDavid du Colombier for (i = 0; i < Tj; i++)
40219b2ee8SDavid du Colombier if (Tojump[i] == n)
41219b2ee8SDavid du Colombier return;
42219b2ee8SDavid du Colombier for (i = 0; i < Jt; i++)
43219b2ee8SDavid du Colombier if (Jumpto[i] == n)
44219b2ee8SDavid du Colombier return;
457dd7cddfSDavid du Colombier if (Jt >= MAXDSTEP)
467dd7cddfSDavid du Colombier fatal("d_step sequence too long", (char *)0);
47219b2ee8SDavid du Colombier Jumpto[Jt++] = n;
487dd7cddfSDavid du Colombier LastGoto = 1;
49219b2ee8SDavid du Colombier }
50219b2ee8SDavid du Colombier
517dd7cddfSDavid du Colombier static void
Mopup(FILE * fd)52219b2ee8SDavid du Colombier Mopup(FILE *fd)
53312a1df1SDavid du Colombier { int i, j;
547dd7cddfSDavid du Colombier
55219b2ee8SDavid du Colombier for (i = 0; i < Jt; i++)
56219b2ee8SDavid du Colombier { for (j = 0; j < Tj; j++)
577dd7cddfSDavid du Colombier if (Tojump[j] == Jumpto[i])
58219b2ee8SDavid du Colombier break;
59219b2ee8SDavid du Colombier if (j == Tj)
6000d97012SDavid du Colombier { char buf[16];
617dd7cddfSDavid du Colombier if (Jumpto[i] == OkBreak)
627dd7cddfSDavid du Colombier { if (!LastGoto)
637dd7cddfSDavid du Colombier fprintf(fd, "S_%.3d_0: /* break-dest */\n",
647dd7cddfSDavid du Colombier OkBreak);
657dd7cddfSDavid du Colombier } else {
66219b2ee8SDavid du Colombier sprintf(buf, "S_%.3d_0", Jumpto[i]);
67219b2ee8SDavid du Colombier non_fatal("goto %s breaks from d_step seq", buf);
687dd7cddfSDavid du Colombier } } }
69219b2ee8SDavid du Colombier for (j = 0; j < Tj; j++)
70219b2ee8SDavid du Colombier { for (i = 0; i < Jt; i++)
717dd7cddfSDavid du Colombier if (Tojump[j] == Jumpto[i])
72219b2ee8SDavid du Colombier break;
73219b2ee8SDavid du Colombier #ifdef DEBUG
74219b2ee8SDavid du Colombier if (i == Jt && !Special[i])
757dd7cddfSDavid du Colombier fprintf(fd, "\t\t/* no goto's to S_%.3d_0 */\n",
76219b2ee8SDavid du Colombier Tojump[j]);
77219b2ee8SDavid du Colombier #endif
78219b2ee8SDavid du Colombier }
79219b2ee8SDavid du Colombier for (j = i = 0; j < Tj; j++)
807dd7cddfSDavid du Colombier if (Special[j])
81*de2caf28SDavid du Colombier { if (i >= MAXDSTEP)
82*de2caf28SDavid du Colombier { fatal("cannot happen (dstep.c)", (char *)0);
83*de2caf28SDavid du Colombier }
84*de2caf28SDavid du Colombier Tojump[i] = Tojump[j];
85219b2ee8SDavid du Colombier Special[i] = 2;
86219b2ee8SDavid du Colombier i++;
877dd7cddfSDavid du Colombier }
88219b2ee8SDavid du Colombier Tj = i; /* keep only the global exit-labels */
89219b2ee8SDavid du Colombier Jt = 0;
90219b2ee8SDavid du Colombier }
91219b2ee8SDavid du Colombier
927dd7cddfSDavid du Colombier static int
FirstTime(int n)93219b2ee8SDavid du Colombier FirstTime(int n)
94219b2ee8SDavid du Colombier { int i;
95219b2ee8SDavid du Colombier for (i = 0; i < Tj; i++)
96219b2ee8SDavid du Colombier if (Tojump[i] == n)
97219b2ee8SDavid du Colombier return (Special[i] <= 1);
98219b2ee8SDavid du Colombier return 1;
99219b2ee8SDavid du Colombier }
100219b2ee8SDavid du Colombier
1017dd7cddfSDavid du Colombier static void
illegal(Element * e,char * str)102219b2ee8SDavid du Colombier illegal(Element *e, char *str)
103219b2ee8SDavid du Colombier {
1047dd7cddfSDavid du Colombier printf("illegal operator in 'd_step:' '");
105219b2ee8SDavid du Colombier comment(stdout, e->n, 0);
106219b2ee8SDavid du Colombier printf("'\n");
1077dd7cddfSDavid du Colombier fatal("'%s'", str);
108219b2ee8SDavid du Colombier }
109219b2ee8SDavid du Colombier
1107dd7cddfSDavid du Colombier static void
filterbad(Element * e)111219b2ee8SDavid du Colombier filterbad(Element *e)
112219b2ee8SDavid du Colombier {
113219b2ee8SDavid du Colombier switch (e->n->ntyp) {
114219b2ee8SDavid du Colombier case ASSERT:
115219b2ee8SDavid du Colombier case PRINT:
116219b2ee8SDavid du Colombier case 'c':
117219b2ee8SDavid du Colombier /* run cannot be completely undone
118219b2ee8SDavid du Colombier * with sv_save-sv_restor
119219b2ee8SDavid du Colombier */
120219b2ee8SDavid du Colombier if (any_oper(e->n->lft, RUN))
1217dd7cddfSDavid du Colombier illegal(e, "run operator in d_step");
1227dd7cddfSDavid du Colombier
1237dd7cddfSDavid du Colombier /* remote refs inside d_step sequences
1247dd7cddfSDavid du Colombier * would be okay, but they cannot always
1257dd7cddfSDavid du Colombier * be interpreted by the simulator the
1267dd7cddfSDavid du Colombier * same as by the verifier (e.g., for an
1277dd7cddfSDavid du Colombier * error trail)
1287dd7cddfSDavid du Colombier */
1297dd7cddfSDavid du Colombier if (any_oper(e->n->lft, 'p'))
1307dd7cddfSDavid du Colombier illegal(e, "remote reference in d_step");
131219b2ee8SDavid du Colombier break;
132219b2ee8SDavid du Colombier case '@':
133219b2ee8SDavid du Colombier illegal(e, "process termination");
134219b2ee8SDavid du Colombier break;
135219b2ee8SDavid du Colombier case D_STEP:
136219b2ee8SDavid du Colombier illegal(e, "nested d_step sequence");
137219b2ee8SDavid du Colombier break;
138219b2ee8SDavid du Colombier case ATOMIC:
139219b2ee8SDavid du Colombier illegal(e, "nested atomic sequence");
140219b2ee8SDavid du Colombier break;
141219b2ee8SDavid du Colombier default:
142219b2ee8SDavid du Colombier break;
143219b2ee8SDavid du Colombier }
144219b2ee8SDavid du Colombier }
145219b2ee8SDavid du Colombier
1467dd7cddfSDavid du Colombier static int
CollectGuards(FILE * fd,Element * e,int inh)147219b2ee8SDavid du Colombier CollectGuards(FILE *fd, Element *e, int inh)
148219b2ee8SDavid du Colombier { SeqList *h; Element *ee;
149219b2ee8SDavid du Colombier
150219b2ee8SDavid du Colombier for (h = e->sub; h; h = h->nxt)
151219b2ee8SDavid du Colombier { ee = huntstart(h->this->frst);
152219b2ee8SDavid du Colombier filterbad(ee);
153219b2ee8SDavid du Colombier switch (ee->n->ntyp) {
1547dd7cddfSDavid du Colombier case NON_ATOMIC:
1557dd7cddfSDavid du Colombier inh += CollectGuards(fd, ee->n->sl->this->frst, inh);
1567dd7cddfSDavid du Colombier break;
157219b2ee8SDavid du Colombier case IF:
158219b2ee8SDavid du Colombier inh += CollectGuards(fd, ee, inh);
159219b2ee8SDavid du Colombier break;
160219b2ee8SDavid du Colombier case '.':
161219b2ee8SDavid du Colombier if (ee->nxt->n->ntyp == DO)
162219b2ee8SDavid du Colombier inh += CollectGuards(fd, ee->nxt, inh);
163219b2ee8SDavid du Colombier break;
164219b2ee8SDavid du Colombier case ELSE:
165219b2ee8SDavid du Colombier if (inh++ > 0) fprintf(fd, " || ");
166*de2caf28SDavid du Colombier /* 4.2.5 */ if (!pid_is_claim(Pid_nr))
167f3793cddSDavid du Colombier fprintf(fd, "(boq == -1 /* else */)");
168f3793cddSDavid du Colombier else
169219b2ee8SDavid du Colombier fprintf(fd, "(1 /* else */)");
170219b2ee8SDavid du Colombier break;
1717dd7cddfSDavid du Colombier case 'R':
172312a1df1SDavid du Colombier if (inh++ > 0) fprintf(fd, " || ");
173312a1df1SDavid du Colombier fprintf(fd, "("); TestOnly=1;
174312a1df1SDavid du Colombier putstmnt(fd, ee->n, ee->seqno);
175312a1df1SDavid du Colombier fprintf(fd, ")"); TestOnly=0;
176312a1df1SDavid du Colombier break;
1777dd7cddfSDavid du Colombier case 'r':
178312a1df1SDavid du Colombier if (inh++ > 0) fprintf(fd, " || ");
179312a1df1SDavid du Colombier fprintf(fd, "("); TestOnly=1;
180312a1df1SDavid du Colombier putstmnt(fd, ee->n, ee->seqno);
181312a1df1SDavid du Colombier fprintf(fd, ")"); TestOnly=0;
182312a1df1SDavid du Colombier break;
1837dd7cddfSDavid du Colombier case 's':
1847dd7cddfSDavid du Colombier if (inh++ > 0) fprintf(fd, " || ");
1857dd7cddfSDavid du Colombier fprintf(fd, "("); TestOnly=1;
186*de2caf28SDavid du Colombier /* 4.2.1 */ if (!pid_is_claim(Pid_nr)) fprintf(fd, "(boq == -1) && ");
1877dd7cddfSDavid du Colombier putstmnt(fd, ee->n, ee->seqno);
1887dd7cddfSDavid du Colombier fprintf(fd, ")"); TestOnly=0;
1897dd7cddfSDavid du Colombier break;
190219b2ee8SDavid du Colombier case 'c':
191219b2ee8SDavid du Colombier if (inh++ > 0) fprintf(fd, " || ");
192219b2ee8SDavid du Colombier fprintf(fd, "("); TestOnly=1;
193*de2caf28SDavid du Colombier if (!pid_is_claim(Pid_nr))
1947dd7cddfSDavid du Colombier fprintf(fd, "(boq == -1 && ");
195219b2ee8SDavid du Colombier putstmnt(fd, ee->n->lft, e->seqno);
196*de2caf28SDavid du Colombier if (!pid_is_claim(Pid_nr))
1977dd7cddfSDavid du Colombier fprintf(fd, ")");
198219b2ee8SDavid du Colombier fprintf(fd, ")"); TestOnly=0;
199219b2ee8SDavid du Colombier break;
2007dd7cddfSDavid du Colombier } }
201219b2ee8SDavid du Colombier return inh;
202219b2ee8SDavid du Colombier }
203219b2ee8SDavid du Colombier
204219b2ee8SDavid du Colombier int
putcode(FILE * fd,Sequence * s,Element * nxt,int justguards,int ln,int seqno)205312a1df1SDavid du Colombier putcode(FILE *fd, Sequence *s, Element *nxt, int justguards, int ln, int seqno)
206*de2caf28SDavid du Colombier { int isg=0;
207*de2caf28SDavid du Colombier static char buf[64];
208219b2ee8SDavid du Colombier
209219b2ee8SDavid du Colombier NextLab[0] = "continue";
210219b2ee8SDavid du Colombier filterbad(s->frst);
211219b2ee8SDavid du Colombier
212219b2ee8SDavid du Colombier switch (s->frst->n->ntyp) {
213219b2ee8SDavid du Colombier case UNLESS:
214219b2ee8SDavid du Colombier non_fatal("'unless' inside d_step - ignored", (char *) 0);
215312a1df1SDavid du Colombier return putcode(fd, s->frst->n->sl->this, nxt, 0, ln, seqno);
216219b2ee8SDavid du Colombier case NON_ATOMIC:
217312a1df1SDavid du Colombier (void) putcode(fd, s->frst->n->sl->this, ZE, 1, ln, seqno);
218*de2caf28SDavid du Colombier if (justguards) return 0; /* 6.2.5 */
219219b2ee8SDavid du Colombier break;
220219b2ee8SDavid du Colombier case IF:
221219b2ee8SDavid du Colombier fprintf(fd, "if (!(");
222312a1df1SDavid du Colombier if (!CollectGuards(fd, s->frst, 0)) /* what about boq? */
223219b2ee8SDavid du Colombier fprintf(fd, "1");
224219b2ee8SDavid du Colombier fprintf(fd, "))\n\t\t\tcontinue;");
225219b2ee8SDavid du Colombier isg = 1;
226219b2ee8SDavid du Colombier break;
227219b2ee8SDavid du Colombier case '.':
228219b2ee8SDavid du Colombier if (s->frst->nxt->n->ntyp == DO)
229219b2ee8SDavid du Colombier { fprintf(fd, "if (!(");
230219b2ee8SDavid du Colombier if (!CollectGuards(fd, s->frst->nxt, 0))
231219b2ee8SDavid du Colombier fprintf(fd, "1");
232219b2ee8SDavid du Colombier fprintf(fd, "))\n\t\t\tcontinue;");
233219b2ee8SDavid du Colombier isg = 1;
234219b2ee8SDavid du Colombier }
235219b2ee8SDavid du Colombier break;
2367dd7cddfSDavid du Colombier case 'R': /* <- can't really happen (it's part of a 'c') */
237219b2ee8SDavid du Colombier fprintf(fd, "if (!("); TestOnly=1;
238219b2ee8SDavid du Colombier putstmnt(fd, s->frst->n, s->frst->seqno);
239219b2ee8SDavid du Colombier fprintf(fd, "))\n\t\t\tcontinue;"); TestOnly=0;
240219b2ee8SDavid du Colombier break;
241312a1df1SDavid du Colombier case 'r':
242312a1df1SDavid du Colombier fprintf(fd, "if (!("); TestOnly=1;
243312a1df1SDavid du Colombier putstmnt(fd, s->frst->n, s->frst->seqno);
244312a1df1SDavid du Colombier fprintf(fd, "))\n\t\t\tcontinue;"); TestOnly=0;
245312a1df1SDavid du Colombier break;
246312a1df1SDavid du Colombier case 's':
247312a1df1SDavid du Colombier fprintf(fd, "if (");
248312a1df1SDavid du Colombier #if 1
249*de2caf28SDavid du Colombier /* 4.2.1 */ if (!pid_is_claim(Pid_nr)) fprintf(fd, "(boq != -1) || ");
250312a1df1SDavid du Colombier #endif
251312a1df1SDavid du Colombier fprintf(fd, "!("); TestOnly=1;
252312a1df1SDavid du Colombier putstmnt(fd, s->frst->n, s->frst->seqno);
253312a1df1SDavid du Colombier fprintf(fd, "))\n\t\t\tcontinue;"); TestOnly=0;
254312a1df1SDavid du Colombier break;
255219b2ee8SDavid du Colombier case 'c':
2567dd7cddfSDavid du Colombier fprintf(fd, "if (!(");
257*de2caf28SDavid du Colombier if (!pid_is_claim(Pid_nr)) fprintf(fd, "boq == -1 && ");
2587dd7cddfSDavid du Colombier TestOnly=1;
259219b2ee8SDavid du Colombier putstmnt(fd, s->frst->n->lft, s->frst->seqno);
260219b2ee8SDavid du Colombier fprintf(fd, "))\n\t\t\tcontinue;"); TestOnly=0;
261219b2ee8SDavid du Colombier break;
262312a1df1SDavid du Colombier case ELSE:
263312a1df1SDavid du Colombier fprintf(fd, "if (boq != -1 || (");
264312a1df1SDavid du Colombier if (separate != 2) fprintf(fd, "trpt->");
265312a1df1SDavid du Colombier fprintf(fd, "o_pm&1))\n\t\t\tcontinue;");
266*de2caf28SDavid du Colombier { extern FILE *fd_th;
267*de2caf28SDavid du Colombier fprintf(fd_th, "#ifndef ELSE_IN_GUARD\n");
268*de2caf28SDavid du Colombier fprintf(fd_th, " #define ELSE_IN_GUARD\n");
269*de2caf28SDavid du Colombier fprintf(fd_th, "#endif\n");
270*de2caf28SDavid du Colombier }
271312a1df1SDavid du Colombier break;
2727dd7cddfSDavid du Colombier case ASGN: /* new 3.0.8 */
2737dd7cddfSDavid du Colombier fprintf(fd, "IfNotBlocked");
2747dd7cddfSDavid du Colombier break;
275*de2caf28SDavid du Colombier default:
276*de2caf28SDavid du Colombier fprintf(fd, "/* default %d */\n\t\t", s->frst->n->ntyp);
277219b2ee8SDavid du Colombier }
278*de2caf28SDavid du Colombier
279*de2caf28SDavid du Colombier /* 6.2.5 : before TstOnly */
280*de2caf28SDavid du Colombier fprintf(fd, "\n\n\t\treached[%d][%d] = 1;\n\t\t", Pid_nr, seqno);
281*de2caf28SDavid du Colombier fprintf(fd, "reached[%d][t->st] = 1;\n\t\t", Pid_nr); /* next state */
282*de2caf28SDavid du Colombier fprintf(fd, "reached[%d][tt] = 1;\n", Pid_nr); /* current state */
283*de2caf28SDavid du Colombier
284*de2caf28SDavid du Colombier /* 6.2.5 : before sv_save() */
285*de2caf28SDavid du Colombier if (s->frst->n->ntyp != NON_ATOMIC)
286*de2caf28SDavid du Colombier fprintf(fd, "\n\t\tif (TstOnly) return 1;\n"); /* if called from enabled() */
287*de2caf28SDavid du Colombier
288219b2ee8SDavid du Colombier if (justguards) return 0;
289219b2ee8SDavid du Colombier
290312a1df1SDavid du Colombier fprintf(fd, "\n\t\tsv_save();\n\t\t");
2917dd7cddfSDavid du Colombier sprintf(buf, "Uerror(\"block in d_step seq, line %d\")", ln);
2927dd7cddfSDavid du Colombier NextLab[0] = buf;
293219b2ee8SDavid du Colombier putCode(fd, s->frst, s->extent, nxt, isg);
294219b2ee8SDavid du Colombier
295219b2ee8SDavid du Colombier if (nxt)
296312a1df1SDavid du Colombier { extern Symbol *Fname;
297312a1df1SDavid du Colombier extern int lineno;
298312a1df1SDavid du Colombier
299312a1df1SDavid du Colombier if (FirstTime(nxt->Seqno)
300219b2ee8SDavid du Colombier && (!(nxt->status & DONE2) || !(nxt->status & D_ATOM)))
301219b2ee8SDavid du Colombier { fprintf(fd, "S_%.3d_0: /* 1 */\n", nxt->Seqno);
302219b2ee8SDavid du Colombier nxt->status |= DONE2;
303219b2ee8SDavid du Colombier LastGoto = 0;
304219b2ee8SDavid du Colombier }
305219b2ee8SDavid du Colombier Sourced(nxt->Seqno, 1);
306312a1df1SDavid du Colombier lineno = ln;
307312a1df1SDavid du Colombier Fname = nxt->n->fn;
308219b2ee8SDavid du Colombier Mopup(fd);
309219b2ee8SDavid du Colombier }
310219b2ee8SDavid du Colombier unskip(s->frst->seqno);
311219b2ee8SDavid du Colombier return LastGoto;
312219b2ee8SDavid du Colombier }
313219b2ee8SDavid du Colombier
3147dd7cddfSDavid du Colombier static void
putCode(FILE * fd,Element * f,Element * last,Element * next,int isguard)315219b2ee8SDavid du Colombier putCode(FILE *fd, Element *f, Element *last, Element *next, int isguard)
316219b2ee8SDavid du Colombier { Element *e, *N;
317219b2ee8SDavid du Colombier SeqList *h; int i;
3187dd7cddfSDavid du Colombier char NextOpt[64];
3197dd7cddfSDavid du Colombier static int bno = 0;
320219b2ee8SDavid du Colombier
321219b2ee8SDavid du Colombier for (e = f; e; e = e->nxt)
322219b2ee8SDavid du Colombier { if (e->status & DONE2)
323219b2ee8SDavid du Colombier continue;
324219b2ee8SDavid du Colombier e->status |= DONE2;
325219b2ee8SDavid du Colombier
326219b2ee8SDavid du Colombier if (!(e->status & D_ATOM))
327219b2ee8SDavid du Colombier { if (!LastGoto)
3287dd7cddfSDavid du Colombier { fprintf(fd, "\t\tgoto S_%.3d_0;\n",
3297dd7cddfSDavid du Colombier e->Seqno);
330219b2ee8SDavid du Colombier Dested(e->Seqno);
331219b2ee8SDavid du Colombier }
332219b2ee8SDavid du Colombier break;
333219b2ee8SDavid du Colombier }
334219b2ee8SDavid du Colombier fprintf(fd, "S_%.3d_0: /* 2 */\n", e->Seqno);
3357dd7cddfSDavid du Colombier LastGoto = 0;
336219b2ee8SDavid du Colombier Sourced(e->Seqno, 0);
337219b2ee8SDavid du Colombier
338219b2ee8SDavid du Colombier if (!e->sub)
339219b2ee8SDavid du Colombier { filterbad(e);
340219b2ee8SDavid du Colombier switch (e->n->ntyp) {
341219b2ee8SDavid du Colombier case NON_ATOMIC:
342219b2ee8SDavid du Colombier h = e->n->sl;
3437dd7cddfSDavid du Colombier putCode(fd, h->this->frst,
3447dd7cddfSDavid du Colombier h->this->extent, e->nxt, 0);
345219b2ee8SDavid du Colombier break;
346219b2ee8SDavid du Colombier case BREAK:
347219b2ee8SDavid du Colombier if (LastGoto) break;
3487dd7cddfSDavid du Colombier if (e->nxt)
3497dd7cddfSDavid du Colombier { i = target( huntele(e->nxt,
350312a1df1SDavid du Colombier e->status, -1))->Seqno;
3517dd7cddfSDavid du Colombier fprintf(fd, "\t\tgoto S_%.3d_0; ", i);
3527dd7cddfSDavid du Colombier fprintf(fd, "/* 'break' */\n");
353219b2ee8SDavid du Colombier Dested(i);
3547dd7cddfSDavid du Colombier } else
3557dd7cddfSDavid du Colombier { if (next)
3567dd7cddfSDavid du Colombier { fprintf(fd, "\t\tgoto S_%.3d_0;",
3577dd7cddfSDavid du Colombier next->Seqno);
3587dd7cddfSDavid du Colombier fprintf(fd, " /* NEXT */\n");
3597dd7cddfSDavid du Colombier Dested(next->Seqno);
3607dd7cddfSDavid du Colombier } else
3617dd7cddfSDavid du Colombier fatal("cannot interpret d_step", 0);
3627dd7cddfSDavid du Colombier }
363219b2ee8SDavid du Colombier break;
364219b2ee8SDavid du Colombier case GOTO:
365219b2ee8SDavid du Colombier if (LastGoto) break;
3667dd7cddfSDavid du Colombier i = huntele( get_lab(e->n,1),
367312a1df1SDavid du Colombier e->status, -1)->Seqno;
3687dd7cddfSDavid du Colombier fprintf(fd, "\t\tgoto S_%.3d_0; ", i);
3697dd7cddfSDavid du Colombier fprintf(fd, "/* 'goto' */\n");
370219b2ee8SDavid du Colombier Dested(i);
371219b2ee8SDavid du Colombier break;
372219b2ee8SDavid du Colombier case '.':
373219b2ee8SDavid du Colombier if (LastGoto) break;
3747dd7cddfSDavid du Colombier if (e->nxt && (e->nxt->status & DONE2))
375*de2caf28SDavid du Colombier { i = e->nxt->Seqno;
3767dd7cddfSDavid du Colombier fprintf(fd, "\t\tgoto S_%.3d_0;", i);
3777dd7cddfSDavid du Colombier fprintf(fd, " /* '.' */\n");
378219b2ee8SDavid du Colombier Dested(i);
379219b2ee8SDavid du Colombier }
380219b2ee8SDavid du Colombier break;
381219b2ee8SDavid du Colombier default:
382219b2ee8SDavid du Colombier putskip(e->seqno);
383219b2ee8SDavid du Colombier GenCode = 1; IsGuard = isguard;
384219b2ee8SDavid du Colombier fprintf(fd, "\t\t");
385219b2ee8SDavid du Colombier putstmnt(fd, e->n, e->seqno);
386219b2ee8SDavid du Colombier fprintf(fd, ";\n");
387219b2ee8SDavid du Colombier GenCode = IsGuard = isguard = LastGoto = 0;
388219b2ee8SDavid du Colombier break;
389219b2ee8SDavid du Colombier }
390219b2ee8SDavid du Colombier i = e->nxt?e->nxt->Seqno:0;
391*de2caf28SDavid du Colombier if (e->nxt && (e->nxt->status & DONE2) && !LastGoto)
3927dd7cddfSDavid du Colombier { fprintf(fd, "\t\tgoto S_%.3d_0; ", i);
3937dd7cddfSDavid du Colombier fprintf(fd, "/* ';' */\n");
394219b2ee8SDavid du Colombier Dested(i);
395219b2ee8SDavid du Colombier break;
396219b2ee8SDavid du Colombier }
397219b2ee8SDavid du Colombier } else
398219b2ee8SDavid du Colombier { for (h = e->sub, i=1; h; h = h->nxt, i++)
3997dd7cddfSDavid du Colombier { sprintf(NextOpt, "goto S_%.3d_%d",
4007dd7cddfSDavid du Colombier e->Seqno, i);
401219b2ee8SDavid du Colombier NextLab[++Level] = NextOpt;
402f3793cddSDavid du Colombier N = (e->n && e->n->ntyp == DO) ? e : e->nxt;
4037dd7cddfSDavid du Colombier putCode(fd, h->this->frst,
4047dd7cddfSDavid du Colombier h->this->extent, N, 1);
405219b2ee8SDavid du Colombier Level--;
406219b2ee8SDavid du Colombier fprintf(fd, "%s: /* 3 */\n", &NextOpt[5]);
4077dd7cddfSDavid du Colombier LastGoto = 0;
408219b2ee8SDavid du Colombier }
409219b2ee8SDavid du Colombier if (!LastGoto)
4107dd7cddfSDavid du Colombier { fprintf(fd, "\t\tUerror(\"blocking sel ");
4117dd7cddfSDavid du Colombier fprintf(fd, "in d_step (nr.%d, near line %d)\");\n",
4127dd7cddfSDavid du Colombier bno++, (e->n)?e->n->ln:0);
413219b2ee8SDavid du Colombier LastGoto = 0;
414219b2ee8SDavid du Colombier }
415219b2ee8SDavid du Colombier }
416219b2ee8SDavid du Colombier if (e == last)
417219b2ee8SDavid du Colombier { if (!LastGoto && next)
4187dd7cddfSDavid du Colombier { fprintf(fd, "\t\tgoto S_%.3d_0;\n",
4197dd7cddfSDavid du Colombier next->Seqno);
420219b2ee8SDavid du Colombier Dested(next->Seqno);
421219b2ee8SDavid du Colombier }
422219b2ee8SDavid du Colombier break;
423219b2ee8SDavid du Colombier } }
424219b2ee8SDavid du Colombier }
425