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