1 /***** spin: pangen1.c *****/
2
3 /*
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
7 */
8
9 #include "spin.h"
10 #include "y.tab.h"
11 #include "pangen1.h"
12 #include "pangen3.h"
13 #include "pangen6.h"
14 #include <assert.h>
15 #ifdef SOLARIS
16 #include <sys/int_limits.h>
17 #else
18 #include <stdint.h>
19 #endif
20
21 extern FILE *fd_tc, *fd_th, *fd_tt;
22 extern Label *labtab;
23 extern Ordered *all_names;
24 extern ProcList *ready;
25 extern Queue *qtab;
26 extern Symbol *Fname;
27 extern int lineno, verbose, Pid_nr, separate, old_scope_rules, nclaims;
28 extern int nrRdy, nrqs, mstp, Mpars, claimnr, eventmapnr;
29 extern short has_sorted, has_random, has_provided, has_priority;
30 extern Queue *ltab[];
31
32 int Npars=0, u_sync=0, u_async=0, hastrack = 1;
33 short has_io = 0;
34 short has_state=0; /* code contains c_state */
35
36 extern void c_add_stack(FILE *);
37 extern void c_stack_size(FILE *);
38
39 static Symbol *LstSet=ZS;
40 static int acceptors=0, progressors=0, nBits=0;
41 static int Types[] = { UNSIGNED, BIT, BYTE, CHAN, MTYPE, SHORT, INT, STRUCT };
42
43 static int doglobal(char *, int);
44 static void dohidden(void);
45 static void do_init(FILE *, Symbol *);
46 static void end_labs(Symbol *, int);
47 static void put_ptype(char *, int, int, int, enum btypes);
48 static void tc_predef_np(void);
49 static void put_pinit(ProcList *);
50 static void multi_init(void);
51 void walk_struct(FILE *, int, char *, Symbol *, char *, char *, char *);
52
53 static void
reverse_names(ProcList * p)54 reverse_names(ProcList *p)
55 {
56 if (!p) return;
57 reverse_names(p->nxt);
58 fprintf(fd_tc, " \"%s\",\n", p->n->name);
59 }
60 static void
reverse_types(ProcList * p)61 reverse_types(ProcList *p)
62 {
63 if (!p) return;
64 reverse_types(p->nxt);
65 fprintf(fd_tc, " %d, /* %s */\n", p->b, p->n->name);
66 }
67
68 static int
blog(int n)69 blog(int n) /* for small log2 without rounding problems */
70 { int m=1, r=2;
71
72 while (r < n) { m++; r *= 2; }
73 return 1+m;
74 }
75
76 void
genheader(void)77 genheader(void)
78 { ProcList *p; int i;
79
80 if (separate == 2)
81 { putunames(fd_th);
82 goto here;
83 }
84 /* 5.2.3: gcc 3 no longer seems to compute sizeof at compile time */
85 fprintf(fd_th, "#define WS %d /* word size in bytes */\n", (int) sizeof(void *));
86 fprintf(fd_th, "#define SYNC %d\n", u_sync);
87 fprintf(fd_th, "#define ASYNC %d\n\n", u_async);
88 fprintf(fd_th, "#ifndef NCORE\n");
89 fprintf(fd_th, " #ifdef DUAL_CORE\n");
90 fprintf(fd_th, " #define NCORE 2\n");
91 fprintf(fd_th, " #elif QUAD_CORE\n");
92 fprintf(fd_th, " #define NCORE 4\n");
93 fprintf(fd_th, " #else\n");
94 fprintf(fd_th, " #define NCORE 1\n");
95 fprintf(fd_th, " #endif\n");
96 fprintf(fd_th, "#endif\n\n");
97
98 putunames(fd_th);
99
100 fprintf(fd_tc, "\nshort Air[] = { ");
101 for (p = ready, i=0; p; p = p->nxt, i++)
102 fprintf(fd_tc, "%s (short) Air%d", (p!=ready)?",":"", i);
103 fprintf(fd_tc, ", (short) Air%d", i); /* np_ */
104 if (nclaims > 1)
105 { fprintf(fd_tc, "\n#ifndef NOCLAIM\n");
106 fprintf(fd_tc, " , (short) Air%d", i+1); /* Multi */
107 fprintf(fd_tc, "\n#endif\n\t");
108 }
109 fprintf(fd_tc, " };\n");
110
111 fprintf(fd_tc, "char *procname[] = {\n");
112 reverse_names(ready);
113 fprintf(fd_tc, " \":np_:\",\n");
114 fprintf(fd_tc, " 0\n");
115 fprintf(fd_tc, "};\n\n");
116
117 fprintf(fd_tc, "enum btypes { NONE=%d, N_CLAIM=%d,", NONE, N_CLAIM);
118 fprintf(fd_tc, " I_PROC=%d, A_PROC=%d,", I_PROC, A_PROC);
119 fprintf(fd_tc, " P_PROC=%d, E_TRACE=%d, N_TRACE=%d };\n\n",
120 P_PROC, E_TRACE, N_TRACE);
121
122 fprintf(fd_tc, "int Btypes[] = {\n");
123 reverse_types(ready);
124 fprintf(fd_tc, " 0 /* :np_: */\n");
125 fprintf(fd_tc, "};\n\n");
126
127 here:
128 for (p = ready; p; p = p->nxt)
129 put_ptype(p->n->name, p->tn, mstp, nrRdy+1, p->b);
130 /* +1 for np_ */
131 put_ptype("np_", nrRdy, mstp, nrRdy+1, 0);
132
133 if (nclaims > 1)
134 { /* this is the structure that goes into the state-vector
135 * instead of the actual never claims
136 * this assumes that the claims do not have any local variables
137 * this claim records the types and states of all subclaims in an array
138 * NB: not sure if we need the first 3 fields in this structure
139 * it's here for now to avoid breaking some possible dependence
140 * in the calculations above, we were already taking into account
141 * that there is one never-claim, which will now be this one
142 */
143
144 i = blog(mstp);
145 fprintf(fd_th, "\n");
146
147 fprintf(fd_th, "#ifndef NOCLAIM\n");
148 fprintf(fd_th, " #ifndef NP\n");
149 fprintf(fd_th, " #undef VERI\n");
150 fprintf(fd_th, " #define VERI %d\n", nrRdy+1);
151 fprintf(fd_th, " #endif\n");
152 fprintf(fd_th, " #define Pclaim P%d\n\n", nrRdy+1);
153 fprintf(fd_th, "typedef struct P%d {\n", nrRdy+1);
154 fprintf(fd_th, " unsigned _pid : 8; /* always zero */\n");
155 fprintf(fd_th, " unsigned _t : %d; /* active-claim type */\n",
156 blog(nrRdy+1));
157 fprintf(fd_th, " unsigned _p : %d; /* active-claim state */\n",
158 i);
159 fprintf(fd_th, " unsigned _n : %d; /* active-claim index */\n",
160 blog(nclaims));
161 if (i <= UINT8_MAX) /* in stdint.h = UCHAR_MAX from limits.h */
162 { fprintf(fd_th, " uchar c_cur[NCLAIMS]; /* claim-states */\n");
163 } else if (i <= UINT16_MAX) /* really USHRT_MAX from limits.h */
164 { fprintf(fd_th, " ushort c_cur[NCLAIMS]; /* claim-states */\n");
165 } else /* the most unlikely case */
166 { fprintf(fd_th, " uint c_cur[NCLAIMS]; /* claim-states */\n");
167 }
168 fprintf(fd_th, "} P%d;\n", nrRdy+1);
169
170 fprintf(fd_tc, "#ifndef NOCLAIM\n");
171 fprintf(fd_tc, "uchar spin_c_typ[NCLAIMS]; /* claim-types */\n");
172 fprintf(fd_tc, "#endif\n");
173
174 fprintf(fd_th, " #define Air%d (0)\n\n", nrRdy+1);
175 fprintf(fd_th, "#endif\n");
176 /*
177 * find special states as:
178 * stopstate [ claimnr ][ curstate ] == 1
179 * accpstate [ claimnr ][ curstate ]
180 * progstate [ claimnr ][ curstate ]
181 * reached [ claimnr ][ curstate ]
182 * visstate [ claimnr ][ curstate ]
183 * loopstate [ claimnr ][ curstate ]
184 * mapstate [ claimnr ][ curstate ]
185 */
186 } else
187 { fprintf(fd_th, "#define Pclaim P0\n");
188 fprintf(fd_th, "#ifndef NCLAIMS\n");
189 fprintf(fd_th, " #define NCLAIMS 1\n");
190 fprintf(fd_th, "#endif\n");
191 fprintf(fd_tc, "uchar spin_c_typ[NCLAIMS]; /* claim-types */\n");
192 }
193
194 ntimes(fd_th, 0, 1, Head0);
195
196 if (separate != 2)
197 {
198 ntimes(fd_th, 0, 1, Header);
199 fprintf(fd_th, "#define StackSize (");
200 c_stack_size(fd_th);
201 fprintf(fd_th, ")\n");
202
203 c_add_stack(fd_th);
204 ntimes(fd_th, 0, 1, Header0);
205 } else
206 { fprintf(fd_th, "extern char *emalloc(unsigned long);\n");
207 }
208 ntimes(fd_th, 0, 1, Head1);
209
210 LstSet = ZS;
211 (void) doglobal("", PUTV);
212
213 hastrack = c_add_sv(fd_th);
214
215 fprintf(fd_th, "#ifdef TRIX\n");
216 fprintf(fd_th, " /* room for 512 proc+chan ptrs, + safety margin */\n");
217 fprintf(fd_th, " char *_ids_[MAXPROC+MAXQ+4];\n");
218 fprintf(fd_th, "#else\n");
219 fprintf(fd_th, " uchar sv[VECTORSZ];\n");
220 fprintf(fd_th, "#endif\n");
221
222 fprintf(fd_th, "} State");
223 #ifdef SOLARIS
224 fprintf(fd_th,"\n#ifdef GCC\n");
225 fprintf(fd_th, "\t__attribute__ ((aligned(8)))");
226 fprintf(fd_th, "\n#endif\n\t");
227 #endif
228 fprintf(fd_th, ";\n\n");
229
230 fprintf(fd_th, "#ifdef TRIX\n");
231 fprintf(fd_th, "typedef struct TRIX_v6 {\n");
232 fprintf(fd_th, " uchar *body; /* aligned */\n");
233 fprintf(fd_th, "#ifndef BFS\n");
234 fprintf(fd_th, " short modified;\n");
235 fprintf(fd_th, "#endif\n");
236 fprintf(fd_th, " short psize;\n");
237 fprintf(fd_th, " short parent_pid;\n");
238 fprintf(fd_th, " struct TRIX_v6 *nxt;\n");
239 fprintf(fd_th, "} TRIX_v6;\n");
240 fprintf(fd_th, "#endif\n\n");
241
242 fprintf(fd_th, "#define HAS_TRACK %d\n", hastrack);
243 if (0 && hastrack) /* not really a problem */
244 { fprintf(fd_th, "#ifdef BFS_PAR\n");
245 fprintf(fd_th, " #error cannot use BFS_PAR on models with c_track stmnts\n");
246 fprintf(fd_th, "#endif\n");
247 }
248 if (separate != 2)
249 dohidden();
250 }
251
252 void
genaddproc(void)253 genaddproc(void)
254 { ProcList *p;
255 int i = 0;
256
257 if (separate == 2) goto shortcut;
258
259 ntimes(fd_tc, nrRdy+1, nrRdy+2, R2); /* +1 for np_ -- was th */
260
261 fprintf(fd_tc, "#ifdef TRIX\n");
262 fprintf(fd_tc, "int what_p_size(int);\n");
263 fprintf(fd_tc, "int what_q_size(int);\n\n");
264
265 /* the number of processes just changed by 1 (up or down) */
266 /* this means that the channel indices move up or down by one slot */
267 /* not all new channels may have a valid index yet, but we move */
268 /* all of them anyway, as if they existed */
269 ntimes(fd_tc, 0, 1, R7a);
270 fprintf(fd_tc, "#endif\n\n");
271
272 ntimes(fd_tc, 0, 1, R7b);
273
274 fprintf(fd_tc, "int\naddproc(int calling_pid, int priority, int n");
275 for (/* i = 0 */; i < Npars; i++)
276 fprintf(fd_tc, ", int par%d", i);
277
278 ntimes(fd_tc, 0, 1, Addp0);
279 ntimes(fd_tc, 1, nrRdy+1, R5); /* +1 for np_ */
280
281 if (nclaims > 1)
282 { fprintf(fd_tc, "#ifndef NOCLAIM\n");
283 ntimes(fd_tc, nrRdy+1, nrRdy+2, R5);
284 fprintf(fd_tc, "#endif\n");
285 }
286
287 ntimes(fd_tc, 0, 1, Addp1);
288
289 if (has_provided)
290 { fprintf(fd_tt, "\nint\nprovided(int II, unsigned char ot, ");
291 fprintf(fd_tt, "int tt, Trans *t)\n");
292 fprintf(fd_tt, "{\n\tswitch(ot) {\n");
293 }
294 shortcut:
295 if (nclaims > 1)
296 { multi_init();
297 }
298 tc_predef_np();
299 for (p = ready; p; p = p->nxt)
300 { Pid_nr = p->tn;
301 put_pinit(p);
302 }
303 if (separate == 2) return;
304
305 Pid_nr = 0;
306 if (has_provided)
307 { fprintf(fd_tt, "\tdefault: return 1; /* e.g., a claim */\n");
308 fprintf(fd_tt, "\t}\n\treturn 0;\n}\n");
309 }
310
311 ntimes(fd_tc, i, i+1, R6);
312 if (separate == 0)
313 ntimes(fd_tc, 1, nrRdy+1, R5); /* +1 for np_ */
314 else
315 ntimes(fd_tc, 1, nrRdy, R5);
316 ntimes(fd_tc, 0, 1, R8a);
317 }
318
319 void
do_locinits(FILE * fd)320 do_locinits(FILE *fd)
321 { ProcList *p;
322
323 /* the locinit functions may refer to pptr or qptr */
324 fprintf(fd, "#if VECTORSZ>32000\n");
325 fprintf(fd, " extern int \n");
326 fprintf(fd, "#else\n");
327 fprintf(fd, " extern short \n");
328 fprintf(fd, "#endif\n");
329 fprintf(fd, " *proc_offset, *q_offset;\n");
330
331 for (p = ready; p; p = p->nxt)
332 { c_add_locinit(fd, p->tn, p->n->name);
333 }
334 }
335
336 void
genother(void)337 genother(void)
338 { ProcList *p;
339
340 switch (separate) {
341 case 2:
342 if (nclaims > 0)
343 { for (p = ready; p; p = p->nxt)
344 { if (p->b == N_CLAIM)
345 { ntimes(fd_tc, p->tn, p->tn+1, R0); /* claims only */
346 fprintf(fd_tc, "#ifdef HAS_CODE\n");
347 ntimes(fd_tc, p->tn, p->tn+1, R00);
348 fprintf(fd_tc, "#endif\n");
349 } } }
350 break;
351 case 1:
352 ntimes(fd_tc, 0, 1, Code0);
353 for (p = ready; p; p = p->nxt)
354 { if (p->b != N_CLAIM)
355 { ntimes(fd_tc, p->tn, p->tn+1, R0); /* all except claims */
356 fprintf(fd_tc, "#ifdef HAS_CODE\n");
357 ntimes(fd_tc, p->tn, p->tn+1, R00);
358 fprintf(fd_tc, "#endif\n");
359 } }
360 break;
361 case 0:
362 ntimes(fd_tc, 0, 1, Code0);
363 ntimes(fd_tc, 0, nrRdy+1, R0); /* +1 for np_ */
364 fprintf(fd_tc, "#ifdef HAS_CODE\n");
365 ntimes(fd_tc, 0, nrRdy+1, R00); /* +1 for np_ */
366 fprintf(fd_tc, "#endif\n");
367 break;
368 }
369 /* new place, make sure Maxbody is set to its final value here */
370 fprintf(fd_tc, "\n");
371
372 if (separate != 2)
373 { ntimes(fd_tc, 1, u_sync+u_async+1, R3); /* nrqs is still 0 */
374 fprintf(fd_tc, "\tMaxbody = max(Maxbody, sizeof(State)-VECTORSZ);\n");
375 fprintf(fd_tc, "\tif ((Maxbody %% WS) != 0)\n");
376 fprintf(fd_tc, "\t Maxbody += WS - (Maxbody %% WS);\n\n");
377 }
378
379 for (p = ready; p; p = p->nxt)
380 end_labs(p->n, p->tn);
381
382 switch (separate) {
383 case 2:
384 if (nclaims > 0)
385 { for (p = ready; p; p = p->nxt)
386 { if (p->b == N_CLAIM)
387 { ntimes(fd_tc, p->tn, p->tn+1, R0a); /* claims only */
388 } } }
389 return;
390 case 1:
391 for (p = ready; p; p = p->nxt)
392 { if (p->b != N_CLAIM)
393 { ntimes(fd_tc, p->tn, p->tn+1, R0a); /* all except claims */
394 } }
395 fprintf(fd_tc, " if (state_tables)\n");
396 fprintf(fd_tc, " ini_claim(%d, 0);\n", claimnr); /* the default claim */
397 if (acceptors == 0)
398 { acceptors = 1; /* assume at least 1 acceptstate */
399 }
400 break;
401 case 0:
402 ntimes(fd_tc, 0, nrRdy, R0a); /* all */
403 break;
404 }
405
406 ntimes(fd_th, acceptors, acceptors+1, Code1);
407 ntimes(fd_th, progressors, progressors+1, Code3);
408
409 ntimes(fd_tc, 0, 1, Code2a); /* dfs, bfs */
410 ntimes(fd_tc, 0, 1, Code2e); /* multicore */
411 ntimes(fd_tc, 0, 1, Code2c); /* multicore */
412 ntimes(fd_tc, 0, 1, Code2d);
413
414 fprintf(fd_tc, "void\ndo_reach(void)\n{\n");
415 ntimes(fd_tc, 0, nrRdy, R4);
416 fprintf(fd_tc, "}\n\n");
417
418 fprintf(fd_tc, "void\niniglobals(int calling_pid)\n{\n");
419 if (doglobal("", INIV) > 0)
420 { fprintf(fd_tc, "#ifdef VAR_RANGES\n");
421 (void) doglobal("logval(\"", LOGV);
422 fprintf(fd_tc, "#endif\n");
423 }
424 fprintf(fd_tc, "}\n\n");
425 }
426
427 void
gensvmap(void)428 gensvmap(void)
429 {
430 ntimes(fd_tc, 0, 1, SvMap);
431 }
432
433 static struct {
434 char *s, *t; int n, m, p;
435 } ln[] = {
436 {"end", "stopstate", 3, 0, 0},
437 {"progress", "progstate", 8, 0, 1},
438 {"accept", "accpstate", 6, 1, 0},
439 {0, 0, 0, 0, 0},
440 };
441
442 static void
end_labs(Symbol * s,int i)443 end_labs(Symbol *s, int i)
444 { int oln = lineno;
445 Symbol *ofn = Fname;
446 Label *l;
447 int j; char foo[128];
448
449 if ((pid_is_claim(i) && separate == 1)
450 || (!pid_is_claim(i) && separate == 2))
451 return;
452
453 for (l = labtab; l; l = l->nxt)
454 for (j = 0; ln[j].n; j++)
455 { if (strncmp(l->s->name, ln[j].s, ln[j].n) == 0
456 && strcmp(l->c->name, s->name) == 0)
457 { fprintf(fd_tc, "\t%s[%d][%d] = 1;\n",
458 ln[j].t, i, l->e->seqno);
459 acceptors += ln[j].m;
460 progressors += ln[j].p;
461 if (l->e->status & D_ATOM)
462 { sprintf(foo, "%s label inside d_step",
463 ln[j].s);
464 goto complain;
465 }
466 if (j > 0 && (l->e->status & ATOM))
467 { sprintf(foo, "%s label inside atomic",
468 ln[j].s);
469 complain: lineno = l->e->n->ln;
470 Fname = l->e->n->fn;
471 printf("spin: %3d:%s, warning, %s - is invisible\n",
472 lineno, Fname?Fname->name:"-", foo);
473 } } }
474 /* visible states -- through remote refs: */
475 for (l = labtab; l; l = l->nxt)
476 if (l->visible
477 && strcmp(l->s->context->name, s->name) == 0)
478 fprintf(fd_tc, "\tvisstate[%d][%d] = 1;\n",
479 i, l->e->seqno);
480
481 lineno = oln;
482 Fname = ofn;
483 }
484
485 void
ntimes(FILE * fd,int n,int m,const char * c[])486 ntimes(FILE *fd, int n, int m, const char *c[])
487 {
488 int i, j;
489 for (j = 0; c[j]; j++)
490 for (i = n; i < m; i++)
491 { fprintf(fd, c[j], i, i, i, i, i, i);
492 fprintf(fd, "\n");
493 }
494 }
495
496 void
prehint(Symbol * s)497 prehint(Symbol *s)
498 { Lextok *n;
499
500 printf("spin: warning, ");
501 if (!s) return;
502
503 n = (s->context != ZS)?s->context->ini:s->ini;
504 if (n)
505 printf("line %s:%d, ", n->fn->name, n->ln);
506 }
507
508 void
checktype(Symbol * sp,char * s)509 checktype(Symbol *sp, char *s)
510 { char buf[128]; int i;
511
512 if (!s
513 || (sp->type != BYTE
514 && sp->type != SHORT
515 && sp->type != INT))
516 return;
517
518 if (sp->hidden&16) /* formal parameter */
519 { ProcList *p; Lextok *f, *t;
520 int posnr = 0;
521 for (p = ready; p; p = p->nxt)
522 if (p->n->name
523 && strcmp(s, p->n->name) == 0)
524 break;
525 if (p)
526 for (f = p->p; f; f = f->rgt) /* list of types */
527 for (t = f->lft; t; t = t->rgt, posnr++)
528 if (t->sym
529 && strcmp(t->sym->name, sp->name) == 0)
530 { checkrun(sp, posnr);
531 return;
532 }
533
534 } else if (!(sp->hidden&4))
535 { if (!(verbose&32)) return;
536 sputtype(buf, sp->type);
537 i = (int) strlen(buf);
538 while (i > 0 && buf[--i] == ' ') buf[i] = '\0';
539 prehint(sp);
540 if (sp->context)
541 printf("proctype %s:", s);
542 else
543 printf("global");
544 printf(" '%s %s' could be declared 'bit %s'\n",
545 buf, sp->name, sp->name);
546 } else if (sp->type != BYTE && !(sp->hidden&8))
547 { if (!(verbose&32)) return;
548 sputtype(buf, sp->type);
549 i = (int) strlen(buf);
550 while (buf[--i] == ' ') buf[i] = '\0';
551 prehint(sp);
552 if (sp->context)
553 printf("proctype %s:", s);
554 else
555 printf("global");
556 printf(" '%s %s' could be declared 'byte %s'\n",
557 buf, sp->name, sp->name);
558 }
559 }
560
561 static int
dolocal(FILE * ofd,char * pre,int dowhat,int p,char * s,enum btypes b)562 dolocal(FILE *ofd, char *pre, int dowhat, int p, char *s, enum btypes b)
563 { int h, j, k=0; extern int nr_errs;
564 Ordered *walk;
565 Symbol *sp;
566 char buf[128], buf2[128], buf3[128];
567
568 if (dowhat == INIV)
569 { /* initialize in order of declaration */
570 for (walk = all_names; walk; walk = walk->next)
571 { sp = walk->entry;
572 if (sp->context
573 && !sp->owner
574 && strcmp(s, sp->context->name) == 0)
575 { checktype(sp, s); /* fall through */
576 if (!(sp->hidden&16))
577 { sprintf(buf, "((P%d *)pptr(h))->", p);
578 do_var(ofd, dowhat, buf, sp, "", " = ", ";\n");
579 }
580 k++;
581 } }
582 } else
583 { for (j = 0; j < 8; j++)
584 for (h = 0; h <= 1; h++)
585 for (walk = all_names; walk; walk = walk->next)
586 { sp = walk->entry;
587 if (sp->context
588 && !sp->owner
589 && sp->type == Types[j]
590 && ((h == 0 && (sp->nel == 1 && sp->isarray == 0))
591 || (h == 1 && (sp->nel > 1 || sp->isarray == 1)))
592 && strcmp(s, sp->context->name) == 0)
593 { switch (dowhat) {
594 case LOGV:
595 if (sp->type == CHAN
596 && verbose == 0)
597 break;
598 sprintf(buf, "%s%s:", pre, s);
599 { sprintf(buf2, "\", ((P%d *)pptr(h))->", p);
600 sprintf(buf3, ");\n");
601 }
602 do_var(ofd, dowhat, "", sp, buf, buf2, buf3);
603 break;
604 case PUTV:
605 sprintf(buf, "((P%d *)pptr(h))->", p);
606 do_var(ofd, dowhat, buf, sp, "", " = ", ";\n");
607 k++;
608 break;
609 }
610 if (b == N_CLAIM)
611 { printf("error: %s defines local %s\n",
612 s, sp->name);
613 nr_errs++;
614 } } } }
615
616 return k;
617 }
618
619 void
c_chandump(FILE * fd)620 c_chandump(FILE *fd)
621 { Queue *q;
622 char buf[256];
623 int i;
624
625 if (!qtab)
626 { fprintf(fd, "void\nc_chandump(int unused)\n");
627 fprintf(fd, "{\tunused++; /* avoid complaints */\n}\n");
628 return;
629 }
630
631 fprintf(fd, "void\nc_chandump(int from)\n");
632 fprintf(fd, "{ uchar *z; int slot;\n");
633
634 fprintf(fd, " from--;\n");
635 fprintf(fd, " if (from >= (int) now._nr_qs || from < 0)\n");
636 fprintf(fd, " { printf(\"pan: bad qid %%d\\n\", from+1);\n");
637 fprintf(fd, " return;\n");
638 fprintf(fd, " }\n");
639 fprintf(fd, " z = qptr(from);\n");
640 fprintf(fd, " switch (((Q0 *)z)->_t) {\n");
641
642 for (q = qtab; q; q = q->nxt)
643 { fprintf(fd, " case %d:\n\t\t", q->qid);
644 sprintf(buf, "((Q%d *)z)->", q->qid);
645
646 fprintf(fd, "for (slot = 0; slot < %sQlen; slot++)\n\t\t", buf);
647 fprintf(fd, "{ printf(\" [\");\n\t\t");
648 for (i = 0; i < q->nflds; i++)
649 { if (q->fld_width[i] == MTYPE)
650 { fprintf(fd, "\tprintm(%scontents[slot].fld%d",
651 buf, i);
652 if (q->mtp[i])
653 { fprintf(fd, ", \"%s\"", q->mtp[i]);
654 } else
655 { fprintf(fd, ", 0");
656 }
657 } else
658 { fprintf(fd, "\tprintf(\"%%d,\", %scontents[slot].fld%d",
659 buf, i);
660 }
661 fprintf(fd, ");\n\t\t");
662 }
663 fprintf(fd, " printf(\"],\");\n\t\t");
664 fprintf(fd, "}\n\t\t");
665 fprintf(fd, "break;\n");
666 }
667 fprintf(fd, " }\n");
668 fprintf(fd, " printf(\"\\n\");\n}\n");
669 }
670
671 void
c_var(FILE * fd,char * pref,Symbol * sp)672 c_var(FILE *fd, char *pref, Symbol *sp)
673 { char *ptr, buf[256];
674 int i;
675
676 if (!sp)
677 { fatal("cannot happen - c_var", 0);
678 }
679
680 ptr = sp->name;
681 if (!old_scope_rules)
682 { while (*ptr == '_' || isdigit((int)*ptr))
683 { ptr++;
684 } }
685
686 switch (sp->type) {
687 case STRUCT:
688 /* c_struct(fd, pref, sp); */
689 fprintf(fd, "\t\tprintf(\"\t(struct %s)\\n\");\n",
690 sp->name);
691 sprintf(buf, "%s%s.", pref, sp->name);
692 c_struct(fd, buf, sp);
693 break;
694 case MTYPE:
695 case BIT: case BYTE:
696 case SHORT: case INT:
697 case UNSIGNED:
698 sputtype(buf, sp->type);
699 if (sp->nel == 1 && sp->isarray == 0)
700 {
701 if (sp->type == MTYPE && ismtype(sp->name))
702 { fprintf(fd, "\tprintf(\"\t%s %s:\t%d\\n\");\n",
703 buf, ptr, ismtype(sp->name));
704 } else
705 { fprintf(fd, "\tprintf(\"\t%s %s:\t%%d\\n\", %s%s);\n",
706 buf, ptr, pref, sp->name);
707 }
708 } else
709 { fprintf(fd, "\t{\tint l_in;\n");
710 fprintf(fd, "\t\tfor (l_in = 0; l_in < %d; l_in++)\n", sp->nel);
711 fprintf(fd, "\t\t{\n");
712 fprintf(fd, "\t\t\tprintf(\"\t%s %s[%%d]:\t%%d\\n\", l_in, %s%s[l_in]);\n",
713 buf, ptr, pref, sp->name);
714 fprintf(fd, "\t\t}\n");
715 fprintf(fd, "\t}\n");
716 }
717 break;
718 case CHAN:
719 if (sp->nel == 1 && sp->isarray == 0)
720 { fprintf(fd, "\tprintf(\"\tchan %s (=%%d):\tlen %%d:\\t\", ", ptr);
721 fprintf(fd, "%s%s, q_len(%s%s));\n",
722 pref, sp->name, pref, sp->name);
723 fprintf(fd, "\tc_chandump(%s%s);\n", pref, sp->name);
724 } else
725 for (i = 0; i < sp->nel; i++)
726 { fprintf(fd, "\tprintf(\"\tchan %s[%d] (=%%d):\tlen %%d:\\t\", ",
727 ptr, i);
728 fprintf(fd, "%s%s[%d], q_len(%s%s[%d]));\n",
729 pref, sp->name, i, pref, sp->name, i);
730 fprintf(fd, "\tc_chandump(%s%s[%d]);\n",
731 pref, sp->name, i);
732 }
733 break;
734 }
735 }
736
737 int
c_splurge_any(ProcList * p)738 c_splurge_any(ProcList *p)
739 { Ordered *walk;
740 Symbol *sp;
741
742 if (p->b != N_CLAIM && p->b != E_TRACE && p->b != N_TRACE)
743 for (walk = all_names; walk; walk = walk->next)
744 { sp = walk->entry;
745 if (!sp->context
746 || sp->type == 0
747 || strcmp(sp->context->name, p->n->name) != 0
748 || sp->owner || (sp->hidden&1)
749 || (sp->type == MTYPE && ismtype(sp->name)))
750 continue;
751
752 return 1;
753 }
754 return 0;
755 }
756
757 void
c_splurge(FILE * fd,ProcList * p)758 c_splurge(FILE *fd, ProcList *p)
759 { Ordered *walk;
760 Symbol *sp;
761 char pref[64];
762
763 if (p->b != N_CLAIM && p->b != E_TRACE && p->b != N_TRACE)
764 for (walk = all_names; walk; walk = walk->next)
765 { sp = walk->entry;
766 if (!sp->context
767 || sp->type == 0
768 || strcmp(sp->context->name, p->n->name) != 0
769 || sp->owner || (sp->hidden&1)
770 || (sp->type == MTYPE && ismtype(sp->name)))
771 continue;
772
773 sprintf(pref, "((P%d *)pptr(pid))->", p->tn);
774 c_var(fd, pref, sp);
775 }
776 }
777
778 void
c_wrapper(FILE * fd)779 c_wrapper(FILE *fd) /* allow pan.c to print out global sv entries */
780 { Ordered *walk;
781 ProcList *p;
782 Symbol *sp;
783 Mtypes_t *lst;
784 Lextok *n;
785 int j;
786 extern Mtypes_t *Mtypes;
787
788 fprintf(fd, "void\nc_globals(void)\n{\t/* int i; */\n");
789 fprintf(fd, " printf(\"global vars:\\n\");\n");
790 for (walk = all_names; walk; walk = walk->next)
791 { sp = walk->entry;
792 if (sp->context || sp->owner || (sp->hidden&1))
793 continue;
794 c_var(fd, "now.", sp);
795 }
796 fprintf(fd, "}\n");
797
798 fprintf(fd, "void\nc_locals(int pid, int tp)\n{\t/* int i; */\n");
799 fprintf(fd, " switch(tp) {\n");
800 for (p = ready; p; p = p->nxt)
801 { fprintf(fd, " case %d:\n", p->tn);
802 if (c_splurge_any(p))
803 { fprintf(fd, " \tprintf(\"local vars proc %%d (%s):\\n\", pid);\n",
804 p->n->name);
805 c_splurge(fd, p);
806 } else
807 { fprintf(fd, " \t/* none */\n");
808 }
809 fprintf(fd, " \tbreak;\n");
810 }
811 fprintf(fd, " }\n}\n");
812
813 fprintf(fd, "void\nprintm(int x, char *s)\n{\n");
814 fprintf(fd, " if (!s) { s = \"_unnamed_\"; }\n");
815 for (lst = Mtypes; lst; lst = lst->nxt)
816 { fprintf(fd, " if (strcmp(s, \"%s\") == 0)\n", lst->nm);
817 fprintf(fd, " switch (x) {\n");
818 for (n = lst->mt, j = 1; n && j; n = n->rgt, j++)
819 fprintf(fd, "\tcase %d: Printf(\"%s\"); return;\n",
820 j, n->lft->sym->name);
821 fprintf(fd, " default: Printf(\"%%d\", x); return;\n");
822 fprintf(fd, " }\n");
823 }
824 fprintf(fd, "}\n");
825 }
826
827 static int
doglobal(char * pre,int dowhat)828 doglobal(char *pre, int dowhat)
829 { Ordered *walk;
830 Symbol *sp;
831 int j, cnt = 0;
832
833 for (j = 0; j < 8; j++)
834 for (walk = all_names; walk; walk = walk->next)
835 { sp = walk->entry;
836 if (!sp->context
837 && !sp->owner
838 && sp->type == Types[j])
839 { if (Types[j] != MTYPE || !ismtype(sp->name))
840 switch (dowhat) {
841 case LOGV:
842 if (sp->type == CHAN
843 && verbose == 0)
844 break;
845 if (sp->hidden&1)
846 break;
847 do_var(fd_tc, dowhat, "", sp,
848 pre, "\", now.", ");\n");
849 break;
850 case INIV:
851 checktype(sp, (char *) 0);
852 cnt++; /* fall through */
853 case PUTV:
854 do_var(fd_tc, dowhat,
855 (sp->hidden&1)?"":"now.", sp,
856 "", " = ", ";\n");
857 break;
858 } } }
859 return cnt;
860 }
861
862 static void
dohidden(void)863 dohidden(void)
864 { Ordered *walk;
865 Symbol *sp;
866 int j;
867
868 for (j = 0; j < 8; j++)
869 for (walk = all_names; walk; walk = walk->next)
870 { sp = walk->entry;
871 if ((sp->hidden&1)
872 && sp->type == Types[j])
873 { if (sp->context || sp->owner)
874 fatal("cannot hide non-globals (%s)", sp->name);
875 if (sp->type == CHAN)
876 fatal("cannot hide channels (%s)", sp->name);
877 fprintf(fd_th, "/* hidden variable: */");
878 typ2c(sp);
879 } }
880 }
881
882 void
do_var(FILE * ofd,int dowhat,char * s,Symbol * sp,char * pre,char * sep,char * ter)883 do_var(FILE *ofd, int dowhat, char *s, Symbol *sp,
884 char *pre, char *sep, char *ter)
885 { int i;
886 char *ptr = sp?sp->name:"";
887
888 if (!sp)
889 { fatal("cannot happen - do_var", 0);
890 }
891
892 switch(dowhat) {
893 case PUTV:
894 if (sp->hidden&1) break;
895
896 typ2c(sp);
897 break;
898
899 case LOGV:
900 if (!old_scope_rules)
901 { while (*ptr == '_' || isdigit((int)*ptr))
902 { ptr++;
903 } }
904 /* fall thru */
905 case INIV:
906 if (sp->type == STRUCT)
907 { /* struct may contain a chan */
908 walk_struct(ofd, dowhat, s, sp, pre, sep, ter);
909 break;
910 }
911 if (!sp->ini && dowhat != LOGV) /* it defaults to 0 */
912 break;
913 if (sp->nel == 1 && sp->isarray == 0)
914 { if (dowhat == LOGV)
915 { fprintf(ofd, "\t\t%s%s%s%s",
916 pre, s, ptr, sep);
917 fprintf(ofd, "%s%s", s, sp->name);
918 } else
919 { fprintf(ofd, "\t\t%s%s%s%s",
920 pre, s, sp->name, sep);
921 do_init(ofd, sp);
922 }
923 fprintf(ofd, "%s", ter);
924 } else
925 { if (sp->ini && sp->ini->ntyp == CHAN)
926 { for (i = 0; i < sp->nel; i++)
927 { fprintf(ofd, "\t\t%s%s%s[%d]%s",
928 pre, s, sp->name, i, sep);
929 if (dowhat == LOGV)
930 fprintf(ofd, "%s%s[%d]",
931 s, sp->name, i);
932 else
933 do_init(ofd, sp);
934 fprintf(ofd, "%s", ter);
935 }
936 } else if (sp->ini)
937 { if (dowhat != LOGV && sp->isarray && sp->ini->ntyp == ',')
938 { Lextok *z, *y;
939 z = sp->ini;
940 for (i = 0; i < sp->nel; i++)
941 { if (z && z->ntyp == ',')
942 { y = z->lft;
943 z = z->rgt;
944 } else
945 { y = z;
946 }
947 fprintf(ofd, "\t\t%s%s%s[%d]%s",
948 pre, s, sp->name, i, sep);
949 putstmnt(ofd, y, 0);
950 fprintf(ofd, "%s", ter);
951 }
952 } else
953 { fprintf(ofd, "\t{\tint l_in;\n");
954 fprintf(ofd, "\t\tfor (l_in = 0; l_in < %d; l_in++)\n",
955 sp->nel);
956 fprintf(ofd, "\t\t{\n");
957 fprintf(ofd, "\t\t\t%s%s%s[l_in]%s",
958 pre, s, sp->name, sep);
959 if (dowhat == LOGV)
960 { fprintf(ofd, "%s%s[l_in]", s, sp->name);
961 } else
962 { putstmnt(ofd, sp->ini, 0);
963 }
964 fprintf(ofd, "%s", ter);
965 fprintf(ofd, "\t\t}\n");
966 fprintf(ofd, "\t}\n");
967 } } }
968 break;
969 }
970 }
971
972 static void
do_init(FILE * ofd,Symbol * sp)973 do_init(FILE *ofd, Symbol *sp)
974 { int i;
975
976 if (sp->ini
977 && sp->type == CHAN
978 && ((i = qmake(sp)) > 0))
979 { if (sp->ini->ntyp == CHAN)
980 { fprintf(ofd, "addqueue(calling_pid, %d, %d)",
981 i, ltab[i-1]->nslots == 0);
982 } else
983 { fprintf(ofd, "%d", i);
984 }
985 } else
986 { putstmnt(ofd, sp->ini, 0);
987 }
988 }
989
990 static void
put_ptype(char * s,int i,int m0,int m1,enum btypes b)991 put_ptype(char *s, int i, int m0, int m1, enum btypes b)
992 { int k;
993
994 if (b == I_PROC)
995 { fprintf(fd_th, "#define Pinit ((P%d *)_this)\n", i);
996 } else if (b == P_PROC || b == A_PROC)
997 { fprintf(fd_th, "#define P%s ((P%d *)_this)\n", s, i);
998 }
999
1000 fprintf(fd_th, "typedef struct P%d { /* %s */\n", i, s);
1001 fprintf(fd_th, " unsigned _pid : 8; /* 0..255 */\n");
1002 fprintf(fd_th, " unsigned _t : %d; /* proctype */\n", blog(m1));
1003 fprintf(fd_th, " unsigned _p : %d; /* state */\n", blog(m0));
1004 fprintf(fd_th, "#ifdef HAS_PRIORITY\n");
1005 fprintf(fd_th, " unsigned _priority : 8; /* 0..255 */\n");
1006 fprintf(fd_th, "#endif\n");
1007 LstSet = ZS;
1008 nBits = 8 + blog(m1) + blog(m0);
1009 k = dolocal(fd_tc, "", PUTV, i, s, b); /* includes pars */
1010 c_add_loc(fd_th, s);
1011
1012 fprintf(fd_th, "} P%d;\n", i);
1013 if ((!LstSet && k > 0) || has_state)
1014 fprintf(fd_th, "#define Air%d 0\n\n", i);
1015 else if (LstSet || k == 0) /* 5.0, added condition */
1016 { fprintf(fd_th, "#define Air%d (sizeof(P%d) - ", i, i);
1017 if (k == 0)
1018 { fprintf(fd_th, "%d", (nBits+7)/8);
1019 goto done;
1020 }
1021 if ((LstSet->type != BIT && LstSet->type != UNSIGNED)
1022 || LstSet->nel != 1)
1023 { fprintf(fd_th, "Offsetof(P%d, %s) - %d*sizeof(",
1024 i, LstSet->name, LstSet->nel);
1025 }
1026 switch(LstSet->type) {
1027 case UNSIGNED:
1028 fprintf(fd_th, "%d", (nBits+7)/8);
1029 break;
1030 case BIT:
1031 if (LstSet->nel == 1)
1032 { fprintf(fd_th, "%d", (nBits+7)/8);
1033 break;
1034 } /* else fall through */
1035 case MTYPE: case BYTE: case CHAN:
1036 fprintf(fd_th, "uchar)"); break;
1037 case SHORT:
1038 fprintf(fd_th, "short)"); break;
1039 case INT:
1040 fprintf(fd_th, "int)"); break;
1041 default:
1042 fatal("cannot happen Air %s",
1043 LstSet->name);
1044 }
1045 done: fprintf(fd_th, ")\n\n");
1046 }
1047 }
1048
1049 static void
tc_predef_np(void)1050 tc_predef_np(void)
1051 {
1052 fprintf(fd_th, "#define _NP_ %d\n", nrRdy); /* 1+ highest proctype nr */
1053
1054 fprintf(fd_th, "#define _nstates%d 3 /* np_ */\n", nrRdy);
1055 fprintf(fd_th, "#define _endstate%d 2 /* np_ */\n\n", nrRdy);
1056 fprintf(fd_th, "#define _start%d 0 /* np_ */\n", nrRdy);
1057
1058 fprintf(fd_tc, "\tcase %d: /* np_ */\n", nrRdy);
1059 if (separate == 1)
1060 { fprintf(fd_tc, "\t\tini_claim(%d, h);\n", nrRdy);
1061 } else
1062 { fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", nrRdy, nrRdy);
1063 fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_p = 0;\n", nrRdy);
1064
1065 fprintf(fd_tc, "#ifdef HAS_PRIORITY\n");
1066 fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_priority = priority;\n", nrRdy);
1067 fprintf(fd_tc, "#endif\n");
1068
1069 fprintf(fd_tc, "\t\treached%d[0] = 1;\n", nrRdy);
1070 fprintf(fd_tc, "\t\taccpstate[%d][1] = 1;\n", nrRdy);
1071 }
1072 fprintf(fd_tc, "\t\tbreak;\n");
1073 }
1074
1075 static void
multi_init(void)1076 multi_init(void)
1077 { ProcList *p;
1078 Element *e;
1079 int i = nrRdy+1;
1080 int ini, j;
1081 int nrc = nclaims;
1082
1083 fprintf(fd_tc, "#ifndef NOCLAIM\n");
1084 fprintf(fd_tc, "\tcase %d: /* claim select */\n", i);
1085 for (p = ready, j = 0; p; p = p->nxt, j++)
1086 { if (p->b == N_CLAIM)
1087 { e = p->s->frst;
1088 ini = huntele(e, e->status, -1)->seqno;
1089
1090 fprintf(fd_tc, "\t\tspin_c_typ[%d] = %d; /* %s */\n",
1091 j, p->tn, p->n->name);
1092 fprintf(fd_tc, "\t\t((P%d *)pptr(h))->c_cur[%d] = %d;\n",
1093 i, j, ini);
1094 fprintf(fd_tc, "\t\treached%d[%d]=1;\n", p->tn, ini);
1095
1096 /* the default initial claim is first one in model */
1097 if (--nrc == 0)
1098 { fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", i, p->tn);
1099 fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_p = %d;\n", i, ini);
1100 fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_n = %d; /* %s */\n",
1101 i, j, p->n->name);
1102 fprintf(fd_tc, "\t\tsrc_claim = src_ln%d;\n", p->tn);
1103 fprintf(fd_tc, "#ifndef BFS\n");
1104 fprintf(fd_tc, "\t\tif (whichclaim == -1 && claimname == NULL)\n");
1105 fprintf(fd_tc, "\t\t\tprintf(\"pan: ltl fomula %s\\n\");\n",
1106 p->n->name);
1107 fprintf(fd_tc, "#endif\n");
1108 }
1109 } }
1110 fprintf(fd_tc, "\t\tif (whichclaim != -1)\n");
1111 fprintf(fd_tc, "\t\t{ select_claim(whichclaim);\n");
1112 fprintf(fd_tc, "\t\t}\n");
1113 fprintf(fd_tc, "\t\tbreak;\n\n");
1114 fprintf(fd_tc, "#endif\n");
1115 }
1116
1117 static void
put_pinit(ProcList * P)1118 put_pinit(ProcList *P)
1119 { Lextok *fp, *fpt, *t;
1120 Element *e = P->s->frst;
1121 Symbol *s = P->n;
1122 Lextok *p = P->p;
1123 int i = P->tn;
1124 int ini, j, k;
1125
1126 if (pid_is_claim(i)
1127 && separate == 1)
1128 { fprintf(fd_tc, "\tcase %d: /* %s */\n", i, s->name);
1129 fprintf(fd_tc, "\t\tini_claim(%d, h);\n", i);
1130 fprintf(fd_tc, "\t\tbreak;\n");
1131 return;
1132 }
1133 if (!pid_is_claim(i)
1134 && separate == 2)
1135 return;
1136
1137 ini = huntele(e, e->status, -1)->seqno;
1138 fprintf(fd_th, "#define _start%d %d\n", i, ini);
1139 if (i == eventmapnr)
1140 fprintf(fd_th, "#define start_event %d\n", ini);
1141
1142 fprintf(fd_tc, "\tcase %d: /* %s */\n", i, s->name);
1143
1144 fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", i, i);
1145 fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_p = %d;\n", i, ini);
1146 fprintf(fd_tc, "#ifdef HAS_PRIORITY\n");
1147
1148 fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_priority = priority; /* was: %d */\n",
1149 i, (P->priority<1)? 1 : P->priority);
1150
1151 fprintf(fd_tc, "#endif\n");
1152 fprintf(fd_tc, "\t\treached%d[%d]=1;\n", i, ini);
1153 if (P->b == N_CLAIM)
1154 { fprintf(fd_tc, "\t\tsrc_claim = src_ln%d;\n", i);
1155 }
1156
1157 if (has_provided)
1158 { fprintf(fd_tt, "\tcase %d: /* %s */\n\t\t", i, s->name);
1159 if (P->prov)
1160 { fprintf(fd_tt, "if (");
1161 putstmnt(fd_tt, P->prov, 0);
1162 fprintf(fd_tt, ")\n\t\t\t");
1163 }
1164 fprintf(fd_tt, "return 1;\n");
1165 if (P->prov)
1166 fprintf(fd_tt, "\t\tbreak;\n");
1167 }
1168
1169 fprintf(fd_tc, "\t\t/* params: */\n");
1170 for (fp = p, j=0; fp; fp = fp->rgt)
1171 for (fpt = fp->lft; fpt; fpt = fpt->rgt, j++)
1172 { t = (fpt->ntyp == ',') ? fpt->lft : fpt;
1173 if (t->sym->nel > 1 || t->sym->isarray)
1174 { lineno = t->ln;
1175 Fname = t->fn;
1176 fatal("array in parameter list, %s",
1177 t->sym->name);
1178 }
1179 fprintf(fd_tc, "\t\t((P%d *)pptr(h))->", i);
1180 if (t->sym->type == STRUCT)
1181 { if (full_name(fd_tc, t, t->sym, 1))
1182 { lineno = t->ln;
1183 Fname = t->fn;
1184 fatal("hidden array in parameter %s",
1185 t->sym->name);
1186 }
1187 } else
1188 fprintf(fd_tc, "%s", t->sym->name);
1189 fprintf(fd_tc, " = par%d;\n", j);
1190 }
1191 fprintf(fd_tc, "\t\t/* locals: */\n");
1192 k = dolocal(fd_tc, "", INIV, i, s->name, P->b);
1193 if (k > 0)
1194 { fprintf(fd_tc, "#ifdef VAR_RANGES\n");
1195 (void) dolocal(fd_tc, "logval(\"", LOGV, i, s->name, P->b);
1196 fprintf(fd_tc, "#endif\n");
1197 }
1198
1199 fprintf(fd_tc, "#ifdef HAS_CODE\n");
1200 fprintf(fd_tc, "\t\tlocinit%d(h);\n", i);
1201 fprintf(fd_tc, "#endif\n");
1202
1203 dumpclaims(fd_tc, i, s->name);
1204 fprintf(fd_tc, "\t break;\n");
1205 }
1206
1207 Element *
huntstart(Element * f)1208 huntstart(Element *f)
1209 { Element *e = f;
1210 Element *elast = (Element *) 0;
1211 int cnt = 0;
1212
1213 while (elast != e && cnt++ < 200) /* new 4.0.8 */
1214 { elast = e;
1215 if (e->n)
1216 { if (e->n->ntyp == '.' && e->nxt)
1217 e = e->nxt;
1218 else if (e->n->ntyp == UNLESS)
1219 e = e->sub->this->frst;
1220 } }
1221
1222 if (cnt >= 200 || !e)
1223 { lineno = (f && f->n)?f->n->ln:lineno;
1224 fatal("confusing control. structure", (char *) 0);
1225 }
1226 return e;
1227 }
1228
1229 Element *
huntele(Element * f,unsigned int o,int stopat)1230 huntele(Element *f, unsigned int o, int stopat)
1231 { Element *g, *e = f;
1232 int cnt=0; /* a precaution against loops */
1233
1234 if (e)
1235 for ( ; cnt < 500 && e->n; cnt++)
1236 {
1237 if (e->seqno == stopat)
1238 break;
1239
1240 switch (e->n->ntyp) {
1241 case GOTO:
1242 g = get_lab(e->n,1);
1243 if (e == g)
1244 { lineno = (f && f->n)?f->n->ln:lineno;
1245 fatal("infinite goto loop", (char *) 0);
1246 }
1247 cross_dsteps(e->n, g->n);
1248 break;
1249 case '.':
1250 case BREAK:
1251 if (!e->nxt)
1252 return e;
1253 g = e->nxt;
1254 break;
1255 case UNLESS:
1256 g = huntele(e->sub->this->frst, o, stopat);
1257 if (!g)
1258 { fatal("unexpected error 1", (char *) 0);
1259 }
1260 break;
1261 case D_STEP:
1262 case ATOMIC:
1263 case NON_ATOMIC:
1264 default:
1265 return e;
1266 }
1267 if ((o & ATOM) && !(g->status & ATOM))
1268 return e;
1269 e = g;
1270 }
1271 if (cnt >= 500 || !e)
1272 { lineno = (f && f->n)?f->n->ln:lineno;
1273 fatal("confusing control structure", (char *) 0);
1274 }
1275 return e;
1276 }
1277
1278 void
typ2c(Symbol * sp)1279 typ2c(Symbol *sp)
1280 { int wsbits = sizeof(long)*8; /* wordsize in bits */
1281 switch (sp->type) {
1282 case UNSIGNED:
1283 if (sp->hidden&1)
1284 fprintf(fd_th, "\tuchar %s;", sp->name);
1285 else
1286 fprintf(fd_th, "\tunsigned %s : %d",
1287 sp->name, sp->nbits);
1288 LstSet = sp;
1289 if (nBits%wsbits > 0
1290 && wsbits - nBits%wsbits < sp->nbits)
1291 { /* must padd to a word-boundary */
1292 nBits += wsbits - nBits%wsbits;
1293 }
1294 nBits += sp->nbits;
1295 break;
1296 case BIT:
1297 if (sp->nel == 1 && sp->isarray == 0 && !(sp->hidden&1))
1298 { fprintf(fd_th, "\tunsigned %s : 1", sp->name);
1299 LstSet = sp;
1300 nBits++;
1301 break;
1302 } /* else fall through */
1303 if (!(sp->hidden&1) && (verbose&32))
1304 printf("spin: warning: bit-array %s[%d] mapped to byte-array\n",
1305 sp->name, sp->nel);
1306 nBits += 8*sp->nel; /* mapped onto array of uchars */
1307 case MTYPE:
1308 case BYTE:
1309 case CHAN: /* good for up to 255 channels */
1310 fprintf(fd_th, "\tuchar %s", sp->name);
1311 LstSet = sp;
1312 break;
1313 case SHORT:
1314 fprintf(fd_th, "\tshort %s", sp->name);
1315 LstSet = sp;
1316 break;
1317 case INT:
1318 fprintf(fd_th, "\tint %s", sp->name);
1319 LstSet = sp;
1320 break;
1321 case STRUCT:
1322 if (!sp->Snm)
1323 fatal("undeclared structure element %s", sp->name);
1324 fprintf(fd_th, "\tstruct %s %s",
1325 sp->Snm->name,
1326 sp->name);
1327 LstSet = ZS;
1328 break;
1329 case CODE_FRAG:
1330 case PREDEF:
1331 return;
1332 default:
1333 fatal("variable %s undeclared", sp->name);
1334 }
1335
1336 if (sp->nel > 1 || sp->isarray)
1337 fprintf(fd_th, "[%d]", sp->nel);
1338 fprintf(fd_th, ";\n");
1339 }
1340
1341 static void
ncases(FILE * fd,int p,int n,int m,const char * c[])1342 ncases(FILE *fd, int p, int n, int m, const char *c[])
1343 { int i, j;
1344
1345 for (j = 0; c[j]; j++)
1346 for (i = n; i < m; i++)
1347 { fprintf(fd, c[j], i, p, i);
1348 fprintf(fd, "\n");
1349 }
1350 }
1351
1352 void
qlen_type(int qmax)1353 qlen_type(int qmax)
1354 {
1355 fprintf(fd_th, "\t");
1356 if (qmax < 256)
1357 fprintf(fd_th, "uchar");
1358 else if (qmax < 65535)
1359 fprintf(fd_th, "ushort");
1360 else
1361 fprintf(fd_th, "uint");
1362 fprintf(fd_th, " Qlen; /* q_size */\n");
1363 }
1364
1365 void
genaddqueue(void)1366 genaddqueue(void)
1367 { char buf0[256];
1368 int j, qmax = 0;
1369 Queue *q;
1370
1371 ntimes(fd_tc, 0, 1, Addq0);
1372
1373 if (has_io && !nrqs)
1374 fprintf(fd_th, "#define NQS 1 /* nrqs=%d, but has_io */\n", nrqs);
1375 else
1376 fprintf(fd_th, "#define NQS %d\n", nrqs);
1377
1378 for (q = qtab; q; q = q->nxt)
1379 if (q->nslots > qmax)
1380 qmax = q->nslots;
1381
1382 for (q = qtab; q; q = q->nxt)
1383 { j = q->qid;
1384 fprintf(fd_tc, "\tcase %d: j = sizeof(Q%d);", j, j);
1385 fprintf(fd_tc, " q_flds[%d] = %d;", j, q->nflds);
1386 fprintf(fd_tc, " q_max[%d] = %d;", j, max(1,q->nslots));
1387 fprintf(fd_tc, " break;\n");
1388
1389 fprintf(fd_th, "typedef struct Q%d {\n", j);
1390 qlen_type(qmax); /* 4.2.2 */
1391 fprintf(fd_th, " uchar _t; /* q_type */\n");
1392 fprintf(fd_th, " struct {\n");
1393
1394 for (j = 0; j < q->nflds; j++)
1395 { switch (q->fld_width[j]) {
1396 case BIT:
1397 if (q->nflds != 1)
1398 { fprintf(fd_th, "\t\tunsigned");
1399 fprintf(fd_th, " fld%d : 1;\n", j);
1400 break;
1401 } /* else fall through: smaller struct */
1402 case MTYPE:
1403 case CHAN:
1404 case BYTE:
1405 fprintf(fd_th, "\t\tuchar fld%d;\n", j);
1406 break;
1407 case SHORT:
1408 fprintf(fd_th, "\t\tshort fld%d;\n", j);
1409 break;
1410 case INT:
1411 fprintf(fd_th, "\t\tint fld%d;\n", j);
1412 break;
1413 default:
1414 fatal("bad channel spec", "");
1415 }
1416 }
1417 fprintf(fd_th, " } contents[%d];\n", max(1, q->nslots));
1418 fprintf(fd_th, "} Q%d;\n", q->qid);
1419 }
1420
1421 fprintf(fd_th, "typedef struct Q0 {\t/* generic q */\n");
1422 qlen_type(qmax); /* 4.2.2 */
1423 fprintf(fd_th, " uchar _t;\n");
1424 fprintf(fd_th, "} Q0;\n");
1425
1426 ntimes(fd_tc, 0, 1, Addq1);
1427
1428 fprintf(fd_tc, "#ifdef TRIX\n");
1429 fprintf(fd_tc, "int\nwhat_p_size(int t)\n{\tint j;\n");
1430 fprintf(fd_tc, " switch (t) {\n");
1431 ntimes(fd_tc, 0, nrRdy+1, R5); /* +1 for np_ */
1432 fprintf(fd_tc, " default: Uerror(\"bad proctype\");\n");
1433 fprintf(fd_tc, " }\n return j;\n}\n\n");
1434
1435 fprintf(fd_tc, "int\nwhat_q_size(int t)\n{\tint j;\n");
1436 fprintf(fd_tc, " switch (t) {\n");
1437 for (j = 0; j < nrqs+1; j++)
1438 { fprintf(fd_tc, " case %d: j = sizeof(Q%d); break;\n", j, j);
1439 }
1440 fprintf(fd_tc, " default: Uerror(\"bad qtype\");\n");
1441 fprintf(fd_tc, " }\n return j;\n}\n");
1442 fprintf(fd_tc, "#endif\n\n");
1443
1444 if (has_random)
1445 { fprintf(fd_th, "int Q_has(int");
1446 for (j = 0; j < Mpars; j++)
1447 fprintf(fd_th, ", int, int");
1448 fprintf(fd_th, ");\n");
1449
1450 fprintf(fd_tc, "int\nQ_has(int into");
1451 for (j = 0; j < Mpars; j++)
1452 fprintf(fd_tc, ", int want%d, int fld%d", j, j);
1453 fprintf(fd_tc, ")\n");
1454 fprintf(fd_tc, "{ int i;\n\n");
1455 fprintf(fd_tc, " if (!into--)\n");
1456 fprintf(fd_tc, " uerror(\"ref to unknown chan ");
1457 fprintf(fd_tc, "(recv-poll)\");\n\n");
1458 fprintf(fd_tc, " if (into >= now._nr_qs || into < 0)\n");
1459 fprintf(fd_tc, " Uerror(\"qrecv bad queue#\");\n\n");
1460 fprintf(fd_tc, " for (i = 0; i < ((Q0 *)qptr(into))->Qlen;");
1461 fprintf(fd_tc, " i++)\n");
1462 fprintf(fd_tc, " {\n");
1463 for (j = 0; j < Mpars; j++)
1464 { fprintf(fd_tc, " if (want%d && ", j);
1465 fprintf(fd_tc, "qrecv(into+1, i, %d, 0) != fld%d)\n",
1466 j, j);
1467 fprintf(fd_tc, " continue;\n");
1468 }
1469 fprintf(fd_tc, " return i+1;\n");
1470 fprintf(fd_tc, " }\n");
1471 fprintf(fd_tc, " return 0;\n");
1472 fprintf(fd_tc, "}\n");
1473 }
1474
1475 fprintf(fd_tc, "#if NQS>0\n");
1476 fprintf(fd_tc, "void\nqsend(int into, int sorted");
1477 for (j = 0; j < Mpars; j++)
1478 fprintf(fd_tc, ", int fld%d", j);
1479 fprintf(fd_tc, ", int args_given)\n");
1480 ntimes(fd_tc, 0, 1, Addq11);
1481
1482 for (q = qtab; q; q = q->nxt)
1483 { sprintf(buf0, "((Q%d *)z)->", q->qid);
1484 fprintf(fd_tc, "\tcase %d:%s\n", q->qid,
1485 (q->nslots)?"":" /* =rv= */");
1486 if (q->nslots == 0) /* reset handshake point */
1487 fprintf(fd_tc, "\t\t(trpt+2)->o_m = 0;\n");
1488
1489 if (has_sorted)
1490 { fprintf(fd_tc, "\t\tif (!sorted) goto append%d;\n", q->qid);
1491 fprintf(fd_tc, "\t\tfor (j = 0; j < %sQlen; j++)\n", buf0);
1492 fprintf(fd_tc, "\t\t{\t/* find insertion point */\n");
1493 sprintf(buf0, "((Q%d *)z)->contents[j].fld", q->qid);
1494 for (j = 0; j < q->nflds; j++)
1495 { fprintf(fd_tc, "\t\t\tif (fld%d > %s%d) continue;\n",
1496 j, buf0, j);
1497 fprintf(fd_tc, "\t\t\tif (fld%d < %s%d) ", j, buf0, j);
1498 fprintf(fd_tc, "goto found%d;\n\n", q->qid);
1499 }
1500 fprintf(fd_tc, "\t\t}\n");
1501 fprintf(fd_tc, "\tfound%d:\n", q->qid);
1502 sprintf(buf0, "((Q%d *)z)->", q->qid);
1503 fprintf(fd_tc, "\t\tfor (k = %sQlen - 1; k >= j; k--)\n", buf0);
1504 fprintf(fd_tc, "\t\t{\t/* shift up */\n");
1505 for (j = 0; j < q->nflds; j++)
1506 { fprintf(fd_tc, "\t\t\t%scontents[k+1].fld%d = ",
1507 buf0, j);
1508 fprintf(fd_tc, "%scontents[k].fld%d;\n",
1509 buf0, j);
1510 }
1511 fprintf(fd_tc, "\t\t}\n");
1512 fprintf(fd_tc, "\tappend%d:\t/* insert in slot j */\n", q->qid);
1513 }
1514
1515 fprintf(fd_tc, "#ifdef HAS_SORTED\n");
1516 fprintf(fd_tc, "\t\t(trpt+1)->ipt = j;\n"); /* ipt was bup.oval */
1517 fprintf(fd_tc, "#endif\n");
1518 fprintf(fd_tc, "\t\t%sQlen = %sQlen + 1;\n", buf0, buf0);
1519 sprintf(buf0, "((Q%d *)z)->contents[j].fld", q->qid);
1520 for (j = 0; j < q->nflds; j++)
1521 { fprintf(fd_tc, "\t\t%s%d = fld%d;", buf0, j, j);
1522 if (q->fld_width[j] == MTYPE)
1523 { fprintf(fd_tc, "\t/* mtype %s */",
1524 q->mtp[j]?q->mtp[j]:"_unnamed_");
1525 }
1526 fprintf(fd_tc, "\n");
1527 }
1528 fprintf(fd_tc, "\t\tif (args_given != %d)\n", q->nflds);
1529 fprintf(fd_tc, "\t\t{ if (args_given > %d)\n", q->nflds);
1530 fprintf(fd_tc, "\t\t uerror(\"too many parameters in send stmnt\");\n");
1531 fprintf(fd_tc, "\t\t else\n");
1532 fprintf(fd_tc, "\t\t uerror(\"too few parameters in send stmnt\");\n");
1533 fprintf(fd_tc, "\t\t}\n");
1534 fprintf(fd_tc, "\t\tbreak;\n");
1535 }
1536 ntimes(fd_tc, 0, 1, Addq2);
1537
1538 for (q = qtab; q; q = q->nxt)
1539 fprintf(fd_tc, "\tcase %d: return %d;\n", q->qid, (!q->nslots));
1540
1541 ntimes(fd_tc, 0, 1, Addq3);
1542
1543 for (q = qtab; q; q = q->nxt)
1544 fprintf(fd_tc, "\tcase %d: return (q_sz(from) == %d);\n",
1545 q->qid, max(1, q->nslots));
1546
1547 ntimes(fd_tc, 0, 1, Addq4);
1548 for (q = qtab; q; q = q->nxt)
1549 { sprintf(buf0, "((Q%d *)z)->", q->qid);
1550 fprintf(fd_tc, " case %d:%s\n\t\t",
1551 q->qid, (q->nslots)?"":" /* =rv= */");
1552 if (q->nflds == 1)
1553 { fprintf(fd_tc, "if (fld == 0) r = %s", buf0);
1554 fprintf(fd_tc, "contents[slot].fld0;\n");
1555 } else
1556 { fprintf(fd_tc, "switch (fld) {\n");
1557 ncases(fd_tc, q->qid, 0, q->nflds, R12);
1558 fprintf(fd_tc, "\t\tdefault: Uerror");
1559 fprintf(fd_tc, "(\"too many fields in recv\");\n");
1560 fprintf(fd_tc, "\t\t}\n");
1561 }
1562 fprintf(fd_tc, "\t\tif (done)\n");
1563 if (q->nslots == 0)
1564 { fprintf(fd_tc, "\t\t{ j = %sQlen - 1;\n", buf0);
1565 fprintf(fd_tc, "\t\t %sQlen = 0;\n", buf0);
1566 sprintf(buf0, "\t\t\t((Q%d *)z)->contents", q->qid);
1567 } else
1568 { fprintf(fd_tc, "\t\t{ j = %sQlen;\n", buf0);
1569 fprintf(fd_tc, "\t\t %sQlen = --j;\n", buf0);
1570 fprintf(fd_tc, "\t\t for (k=slot; k<j; k++)\n");
1571 fprintf(fd_tc, "\t\t {\n");
1572 sprintf(buf0, "\t\t\t((Q%d *)z)->contents", q->qid);
1573 for (j = 0; j < q->nflds; j++)
1574 { fprintf(fd_tc, "\t%s[k].fld%d = \n", buf0, j);
1575 fprintf(fd_tc, "\t\t%s[k+1].fld%d;\n", buf0, j);
1576 }
1577 fprintf(fd_tc, "\t\t }\n");
1578 }
1579
1580 for (j = 0; j < q->nflds; j++)
1581 fprintf(fd_tc, "%s[j].fld%d = 0;\n", buf0, j);
1582 fprintf(fd_tc, "\t\t\tif (fld+1 != %d)\n\t\t\t", q->nflds);
1583 fprintf(fd_tc, "\tuerror(\"missing pars in receive\");\n");
1584 /* incompletely received msgs cannot be unrecv'ed */
1585 fprintf(fd_tc, "\t\t}\n");
1586 fprintf(fd_tc, "\t\tbreak;\n");
1587 }
1588 ntimes(fd_tc, 0, 1, Addq5);
1589 for (q = qtab; q; q = q->nxt)
1590 fprintf(fd_tc, " case %d: j = sizeof(Q%d); break;\n",
1591 q->qid, q->qid);
1592 ntimes(fd_tc, 0, 1, R8b);
1593 ntimes(fd_th, 0, 1, Proto); /* function prototypes */
1594
1595 fprintf(fd_th, "void qsend(int, int");
1596 for (j = 0; j < Mpars; j++)
1597 fprintf(fd_th, ", int");
1598 fprintf(fd_th, ", int);\n\n");
1599
1600 fprintf(fd_th, "#define Addproc(x,y) addproc(256, y, x");
1601 /* 256 is param outside the range of valid pids */
1602 for (j = 0; j < Npars; j++)
1603 fprintf(fd_th, ", 0");
1604 fprintf(fd_th, ")\n");
1605 }
1606