/* $NetBSD: procs.c,v 1.7 2002/05/16 19:30:41 wiz Exp $ */ /* * This code is such a kludge that I don't want to put my name on it. * It was a ridiculously fast hack and needs rewriting. * However it does work... */ #include __KERNEL_RCSID(0, "$NetBSD: procs.c,v 1.7 2002/05/16 19:30:41 wiz Exp $"); #include #include #include #include "malloc.h" #include "main.h" #include "debug.h" #include "sets.h" #include "procs.h" struct Predicate { int p_index; int p_transno; char *p_str; struct Predicate *p_next; }; struct Stateent { int s_index; int s_newstate; int s_action; struct Stateent *s_next; }; struct Object *SameState = (struct Object *)-1; int Index = 0; int Nstates = 0; int Nevents = 0; struct Predicate **Predlist; struct Stateent **Statelist; extern FILE *astringfile; int predtable(); void end_events() { int size, part; char *addr; IFDEBUG(X) /* finish estring[], start astring[] */ if(debug['X'] < 2 ) fprintf(astringfile, "};\n\nchar *%s_astring[] = {\n\"NULLACTION\",\n", protocol); ENDDEBUG /* NOSTRICT */ Statelist = (struct Stateent **) Malloc((Nstates+1) * sizeof(struct Statent *)); /* NOSTRICT */ Predlist = (struct Predicate **) Malloc ( (((Nevents)<BZSIZE?BZSIZE:size; IFDEBUG(N) fprintf(OUT, "bzero addr 0x%p part %d size %d\n",addr, part, size); ENDDEBUG bzero(addr, part); IFDEBUG(N) fprintf(OUT, "after bzero addr 0x%p part %d size %d\n",addr, part, size); ENDDEBUG addr += part; size -= part; } IFDEBUG(N) fprintf(OUT, "endevents..done \n"); ENDDEBUG } int acttable(f,actstring) char *actstring; FILE *f; { static int Actindex = 0; extern FILE *astringfile; extern int pgoption; IFDEBUG(a) fprintf(OUT,"acttable()\n"); ENDDEBUG fprintf(f, "case 0x%x: \n", ++Actindex); if(pgoption) { fprintf(f, "asm(\" # dummy statement\");\n"); fprintf(f, "asm(\"_Xebec_action_%x: \");\n", Actindex ); fprintf(f, "asm(\".data\");\n"); fprintf(f, "asm(\".globl _Xebec_action_%x# X profiling\");\n", Actindex ); fprintf(f, "asm(\".long 0 # X profiling\");\n"); fprintf(f, "asm(\".text # X profiling\");\n"); fprintf(f, "asm(\"cas r0,r15,r0 # X profiling\");\n"); fprintf(f, "asm(\"bali r15,mcount # X profiling\");\n"); } fprintf(f, "\t\t%s\n\t\t break;\n", actstring); IFDEBUG(X) if(debug['X']<2) { register int len = 0; fputc('"',astringfile); while(*actstring) { if( *actstring == '\n' ) { fputc('\\', astringfile); len++; fputc('n', astringfile); } else if (*actstring == '\\') { fputc('\\', astringfile); len ++; fputc('\\', astringfile); } else if (*actstring == '\"') { fputc('\\', astringfile); len ++; fputc('\"', astringfile); } else fputc(*actstring, astringfile); actstring++; len++; } fprintf(astringfile,"\",\n"); if (len > LINELEN) { fprintf(stderr, "Action too long: %d\n",len); Exit(-1); } } ENDDEBUG return(Actindex); } static int Npred=0, Ndefpred=0, Ntrans=0, Ndefevent=0, Nnulla=0; void statetable(string, oldstate, newstate, action, event) char *string; int action; struct Object *oldstate, *newstate, *event; { register int different; IFDEBUG(a) fprintf(OUT,"statetable(0x%p, 0x%p,0x%p, 0x%x)\n", string, oldstate, newstate, action); fprintf(OUT,"statetable(%s, %s,%s, 0x%x)\n", string, oldstate->obj_name, newstate->obj_name, action); ENDDEBUG if( !action) Nnulla++; if( newstate->obj_kind == OBJ_SET) { fprintf(stderr, "Newstate cannot be a set\n"); Exit(-1); } different = (newstate != SameState); (void) predtable( oldstate, event, string, action, (newstate->obj_number) * different ); IFDEBUG(a) fprintf(OUT,"EXIT statetable\n"); ENDDEBUG } void stateentry(index, oldstate, newstate, action) int index, action; int oldstate, newstate; { extern FILE *statevalfile; IFDEBUG(a) fprintf(OUT,"stateentry(0x%x,0x%x,0x%x,0x%x) Statelist@0x%p, val 0x%p\n", index, oldstate, newstate,action, &Statelist, Statelist); ENDDEBUG fprintf(statevalfile, "{0x%x,0x%x},\n", newstate, action); } int predtable(os, oe, str, action, newstate) struct Object *os, *oe; char *str; int action, newstate; { register struct Predicate *p, **q; register int event, state; register struct Object *e, *s; struct Object *firste; if (oe == (struct Object *)0 ) { Ndefevent ++; fprintf(stderr, "DEFAULT EVENTS aren't implemented; trans ignored\n"); return (-1); } Ntrans++; IFDEBUG(g) fprintf(stdout, "PREDTAB: s %5s; e %5s\n", os->obj_kind==OBJ_SET?"SET":"item", oe->obj_kind==OBJ_SET?"SET":"item"); ENDDEBUG if (os->obj_kind == OBJ_SET) s = os->obj_members; else s = os; if (oe->obj_kind == OBJ_SET) firste = oe->obj_members; else firste = oe; if(newstate) { fprintf(statevalfile, "{0x%x,0x%x},\n",newstate, action); Index++; } while (s) { if( !newstate ) { /* !newstate --> SAME */ /* i.e., use old obj_number */ fprintf(statevalfile, "{0x%x,0x%x},\n",s->obj_number, action); Index++; } e = firste; while (e) { event = e->obj_number; state = s->obj_number; IFDEBUG(g) fprintf(stdout,"pred table event=0x%x, state 0x%x\n", event, state); fflush(stdout); ENDDEBUG if( !str /* DEFAULT PREDICATE */) { Ndefpred++; IFDEBUG(g) fprintf(stdout, "DEFAULT pred state 0x%x, event 0x%x, Index 0x%x\n", state, event, Index); fflush(stdout); ENDDEBUG } else Npred++; /* put at END of list */ #ifndef LINT IFDEBUG(g) fprintf(stdout, "predicate for event 0x%x, state 0x%x is 0x%x, %s\n", event, state, Index, str); fflush(stdout); ENDDEBUG #endif /* LINT */ for( ((q = &Predlist[(event<p_next ) { q = &p->p_next; } p = (struct Predicate *)Malloc(sizeof(struct Predicate)); p->p_next = (struct Predicate *)0; p->p_str = str; p->p_index = Index; p->p_transno = transno; *q = p; IFDEBUG(g) fprintf(stdout, "predtable index 0x%x, transno %d, E 0x%p, S 0x%p\n", Index, transno, e, s); ENDDEBUG e = e->obj_members; } s = s->obj_members; } return Index ; } void printprotoerrs() { register int e,s; fprintf(stderr, "[ Event, State ] without any transitions :\n"); for(e = 0; e < Nevents; e++) { fprintf(stderr, "Event 0x%x: states ", e); for(s = 0; s < Nstates; s++) { if( Predlist[(e<p_str) { if(!hadapred) fprintf(f, "case 0x%x:\n\t", (e<p_str, p->p_index); } else { if(defaultindex) { fprintf(stderr, "\nConflict between transitions %d and %d: duplicate default \n", p->p_transno, defaultItrans); Exit(-1); } defaultindex = p->p_index; defaultItrans = p->p_transno; } p = p->p_next; } if( hadapred) { fprintf(f, "return 0x%x;\n", defaultindex); } IFDEBUG(d) fflush(f); ENDDEBUG } IFDEBUG(g) fprintf(stdout, "loop: e 0x%x s 0x%x hadapred 0x%x dindex 0x%x for trans 0x%x\n", e, s, hadapred, defaultindex, defaultItrans); ENDDEBUG if ( hadapred ) { /* put a -1 in the array - Predlist is temporary storage */ Predlist[(e<p_next ) { #ifndef LINT IFDEBUG(a) fprintf(OUT, "dump_pentry for event 0x%x, state 0x%x is 0x%x\n", event, state, p); ENDDEBUG #endif /* LINT */ q = &p->p_next; } } #endif /* notdef */