pangen1.c 40 KB

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