pangen1.c 39 KB

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