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