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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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 * 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 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 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 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 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