1 /***** spin: vars.c *****/
4 * This file is part of the public release of Spin. It is subject to the
5 * terms in the LICENSE file that is included in this source directory.
6 * Tool documentation is available at http://spinroot.com
12 extern Ordered *all_names;
13 extern RunList *X, *LastX;
16 extern int lineno, depth, verbose, xspin, limited_vis;
17 extern int analyze, jumpsteps, nproc, nstop, columns, old_priority_rules;
18 extern short no_arrays, Have_claim;
19 extern void sr_mesg(FILE *, int, int);
20 extern void sr_buf(int, int);
22 static int getglobal(Lextok *);
23 static int setglobal(Lextok *, int);
24 static int maxcolnr = 1;
28 { Symbol *s = sn->sym;
30 if (strcmp(s->name, "_") == 0)
31 { non_fatal("attempt to read value of '_'", 0);
34 if (strcmp(s->name, "_last") == 0)
35 return (LastX)?LastX->pid:0;
36 if (strcmp(s->name, "_p") == 0)
37 return (X && X->pc)?X->pc->seqno:0;
38 if (strcmp(s->name, "_pid") == 0)
40 return X->pid - Have_claim;
42 if (strcmp(s->name, "_priority") == 0)
45 if (old_priority_rules)
46 { non_fatal("cannot refer to _priority with -o6", (char *) 0);
52 if (strcmp(s->name, "_nr_pr") == 0)
53 { return nproc-nstop; /* new 3.3.10 */
56 if (s->context && s->type)
57 { return getlocal(sn);
60 if (!s->type) /* not declared locally */
61 { s = lookup(s->name); /* try global */
62 sn->sym = s; /* fix it */
69 setval(Lextok *v, int n)
71 if (strcmp(v->sym->name, "_last") == 0
72 || strcmp(v->sym->name, "_p") == 0
73 || strcmp(v->sym->name, "_pid") == 0
74 || strcmp(v->sym->name, "_nr_qs") == 0
75 || strcmp(v->sym->name, "_nr_pr") == 0)
76 { non_fatal("illegal assignment to %s", v->sym->name);
78 if (strcmp(v->sym->name, "_priority") == 0)
79 { if (old_priority_rules)
80 { non_fatal("cannot refer to _priority with -o6", (char *) 0);
84 { non_fatal("no context for _priority", (char *) 0);
90 if (v->sym->context && v->sym->type)
91 return setlocal(v, n);
93 v->sym = lookup(v->sym->name);
94 return setglobal(v, n);
98 rm_selfrefs(Symbol *s, Lextok *i)
103 && strcmp(i->sym->name, s->name) == 0
104 && ( (!i->sym->context && !s->context)
105 || ( i->sym->context && s->context
106 && strcmp(i->sym->context->name, s->context->name) == 0)))
109 non_fatal("self-reference initializing '%s'", s->name);
113 { rm_selfrefs(s, i->lft);
114 rm_selfrefs(s, i->rgt);
119 checkvar(Symbol *s, int n)
120 { int i, oln = lineno; /* calls on eval() change it */
121 Symbol *ofnm = Fname;
128 { non_fatal("undecl var %s (assuming int)", s->name);
132 if (s->val == (int *) 0) /* uninitialized */
133 { s->val = (int *) emalloc(s->nel*sizeof(int));
135 for (i = 0; i < s->nel; i++)
136 { if (z && z->ntyp == ',')
146 { s->val[i] = qmake(s);
155 getglobal(Lextok *sn)
156 { Symbol *s = sn->sym;
157 int i, n = eval(sn->lft);
159 if (s->type == 0 && X && (i = find_lab(s, X->n, 0))) /* getglobal */
160 { printf("findlab through getglobal on %s\n", s->name);
161 return i; /* can this happen? */
163 if (s->type == STRUCT)
164 { return Rval_struct(sn, s, 1); /* 1 = check init */
167 { return cast_val(s->type, s->val[n], s->nbits);
173 cast_val(int t, int v, int w)
174 { int i=0; short s=0; unsigned int u=0;
176 if (t == PREDEF || t == INT || t == CHAN) i = v; /* predef means _ */
177 else if (t == SHORT) s = (short) v;
178 else if (t == BYTE || t == MTYPE) u = (unsigned char)v;
179 else if (t == BIT) u = (unsigned char)(v&1);
180 else if (t == UNSIGNED)
182 fatal("cannot happen, cast_val", (char *)0);
183 /* u = (unsigned)(v& ((1<<w)-1)); problem when w=32 */
184 u = (unsigned)(v& (~0u>>(8*sizeof(unsigned)-w))); /* doug */
187 if (v != i+s+ (int) u)
188 { char buf[64]; sprintf(buf, "%d->%d (%d)", v, i+s+(int)u, t);
189 non_fatal("value (%s) truncated in assignment", buf);
191 return (int)(i+s+(int)u);
195 setglobal(Lextok *v, int m)
197 if (v->sym->type == STRUCT)
198 { (void) Lval_struct(v, v->sym, 1, m);
200 { int n = eval(v->lft);
201 if (checkvar(v->sym, n))
202 { int oval = v->sym->val[n];
203 int nval = cast_val(v->sym->type, m, v->sym->nbits);
204 v->sym->val[n] = nval;
206 { v->sym->setat = depth;
212 dumpclaims(FILE *fd, int pid, char *s)
213 { extern Lextok *Xu_List; extern int Pid;
215 Lextok *m; int cnt = 0; int oPid = Pid;
217 for (m = Xu_List; m; m = m->rgt)
218 if (strcmp(m->sym->name, s) == 0)
222 if (cnt == 0) return;
225 fprintf(fd, "#ifndef XUSAFE\n");
226 for (m = Xu_List; m; m = m->rgt)
227 { if (strcmp(m->sym->name, s) != 0)
230 putname(fd, "\t\tsetq_claim(", m->lft, 0, "");
232 fprintf(fd, ", %d, ", m->val);
234 putname(fd, "\"", m->lft, 0, "\", h, ");
236 fprintf(fd, "\"%s\");\n", s);
238 fprintf(fd, "#endif\n");
245 static Lextok *dummy = ZN;
250 dummy = nn(ZN, NAME, nn(ZN,CONST,ZN,ZN), ZN);
252 for (walk = all_names; walk; walk = walk->next)
254 if (!sp->type || sp->context || sp->owner
255 || sp->type == PROCTYPE || sp->type == PREDEF
256 || sp->type == CODE_FRAG || sp->type == CODE_DECL
257 || (sp->type == MTYPE && ismtype(sp->name)))
260 if (sp->type == STRUCT)
261 { if ((verbose&4) && !(verbose&64)
262 && (sp->setat < depth
263 && jumpsteps != depth))
266 dump_struct(sp, sp->name, 0);
269 for (j = 0; j < sp->nel; j++)
271 if (sp->type == CHAN)
275 if ((verbose&4) && !(verbose&64)
276 && (sp->setat < depth
277 && jumpsteps != depth))
283 /* in case of cast_val warnings, do this first: */
284 prefetch = getglobal(dummy);
285 printf("\t\t%s", sp->name);
286 if (sp->nel > 1 || sp->isarray) printf("[%d]", j);
288 sr_mesg(stdout, prefetch,
291 if (limited_vis && (sp->hidden&2))
296 sprintf(Buf, "~G%s = ", sp->name);
298 sprintf(Buf, "%s = ", sp->name);
300 sr_buf(prefetch, sp->type == MTYPE);
302 { sp->colnr = (unsigned char) maxcolnr;
303 maxcolnr = 1+(maxcolnr%10);
305 colpos = nproc+sp->colnr-1;
307 { pstext(colpos, Buf);
311 { printf("\t\t%s\n", Buf);
314 printf("MSC: ~G %s %s\n", sp->name, Buf);
315 printf("%3d:\tproc %3d (TRACK) line 1 \"var\" ",
317 printf("(state 0)\t[printf('MSC: globvar\\\\n')]\n");
318 printf("\t\t%s", sp->name);
319 if (sp->nel > 1 || sp->isarray) printf("[%d]", j);
320 printf(" = %s\n", Buf);
325 dumplocal(RunList *r)
326 { static Lextok *dummy = ZN;
335 dummy = nn(ZN, NAME, nn(ZN,CONST,ZN,ZN), ZN);
337 for (z = s; z; z = z->next)
338 { if (z->type == STRUCT)
339 { dump_struct(z, z->name, r);
342 for (i = 0; i < z->nel; i++)
343 { if (z->type == CHAN)
347 if ((verbose&4) && !(verbose&64)
349 && jumpsteps != depth))
355 printf("\t\t%s(%d):%s",
356 r->n->name, r->pid - Have_claim, z->name);
357 if (z->nel > 1 || z->isarray) printf("[%d]", i);
359 sr_mesg(stdout, getval(dummy), z->type == MTYPE);
361 if (limited_vis && (z->hidden&2))
366 sprintf(Buf, "~G%s(%d):%s = ",
367 r->n->name, r->pid, z->name);
369 sprintf(Buf, "%s(%d):%s = ",
370 r->n->name, r->pid, z->name);
372 sr_buf(getval(dummy), z->type==MTYPE);
374 { z->colnr = (unsigned char) maxcolnr;
375 maxcolnr = 1+(maxcolnr%10);
377 colpos = nproc+z->colnr-1;
379 { pstext(colpos, Buf);
383 { printf("\t\t%s\n", Buf);
386 printf("MSC: ~G %s(%d):%s %s\n",
387 r->n->name, r->pid, z->name, Buf);
389 printf("%3d:\tproc %3d (TRACK) line 1 \"var\" ",
391 printf("(state 0)\t[printf('MSC: locvar\\\\n')]\n");
392 printf("\t\t%s(%d):%s",
393 r->n->name, r->pid, z->name);
394 if (z->nel > 1 || z->isarray) printf("[%d]", i);
395 printf(" = %s\n", Buf);