void * permalloc(int size) { void *rv; if (size > MEMCHUNKSZ) { if ((rv = malloc(size)) == NULL) cerror("permalloc: missing %d bytes", size); return rv; } if (size <= 0) cerror("permalloc2"); if (allocleft < size) { /* looses unused bytes */ lostmem += allocleft; if ((allocpole = malloc(MEMCHUNKSZ)) == NULL) cerror("permalloc: out of memory"); allocleft = MEMCHUNKSZ; } size = ROUNDUP(size); rv = &allocpole[MEMCHUNKSZ-allocleft]; allocleft -= size; permallocsize += size; return rv; }
/* * Allocate off bits on the stack. p is a tree that when evaluated * is the multiply count for off, t is a NAME node where to write * the allocated address. */ void spalloc(NODE *t, NODE *p, OFFSZ off) { NODE *sp; cerror("spalloc"); if ((off % SZINT) == 0) p = buildtree(MUL, p, bcon(off/SZINT)); else if ((off % SZSHORT) == 0) { p = buildtree(MUL, p, bcon(off/SZSHORT)); p = buildtree(PLUS, p, bcon(1)); p = buildtree(RS, p, bcon(1)); } else if ((off % SZCHAR) == 0) { p = buildtree(MUL, p, bcon(off/SZCHAR)); p = buildtree(PLUS, p, bcon(3)); p = buildtree(RS, p, bcon(2)); } else cerror("roundsp"); /* save the address of sp */ sp = block(REG, NIL, NIL, PTR+INT, t->n_df, t->n_ap); sp->n_lval = 0; sp->n_rval = STKREG; t->n_type = sp->n_type; ecomp(buildtree(ASSIGN, t, sp)); /* Emit! */ /* add the size to sp */ sp = block(REG, NIL, NIL, p->n_type, 0, 0); sp->n_lval = 0; sp->n_rval = STKREG; ecomp(buildtree(PLUSEQ, sp, p)); }
/* * Defer message about failure to open file to prevent messing up * alignment of page with tear perforations or form markers. * Treat empty file as special case and report as diagnostic. */ Biobuf* mustopen(char *s, Fils *f) { char *tmp; if(*s == '\0') { f->f_name = STDINNAME(); f->f_f = malloc(sizeof(Biobuf)); if(f->f_f == 0) cerror("no memory"); Binit(f->f_f, 0, OREAD); } else if((f->f_f = Bopen(f->f_name = s, OREAD)) == 0) { tmp = ffiler(f->f_name); s = strcpy((char*)getspace(strlen(tmp) + 1), tmp); free(tmp); } if(f->f_f != 0) { if((f->f_nextc = Bgetrune(f->f_f)) >= 0 || Multi == 'm') return f->f_f; sprint(s = (char*)getspace(strlen(f->f_name) + 1 + EMPTY), "%s -- empty file\n", f->f_name); Bterm(f->f_f); } error = 1; cerror(s); fprint(2, "\n"); return 0; }
/* * add/sub/... * * Param given: */ void hopcode(int f, int o) { char *str = 0; switch (o) { case PLUS: str = "add"; break; case MINUS: str = "sub"; break; case AND: str = "and"; break; case OR: cerror("hopcode OR"); break; case ER: cerror("hopcode xor"); str = "xor"; break; default: comperr("hopcode2: %d", o); str = 0; /* XXX gcc */ } printf("%s%c", str, f); }
/* * Free a node, and return its left descendant. * It is up to the caller to know whether the return value is usable. */ NODE * nfree(NODE *p) { NODE *l; #ifdef PCC_DEBUG_NODES NODE *q; #endif if (p == NULL) cerror("freeing blank node!"); l = p->n_left; if (p->n_op == FREE) cerror("freeing FREE node", p); #ifdef PCC_DEBUG_NODES q = freelink; while (q != NULL) { if (q == p) cerror("freeing free node %p", p); q = q->next; } #endif if (nflag) printf("freeing node %p\n", p); p->n_op = FREE; p->next = freelink; freelink = p; usednodes--; return l; }
void add_var(char* name) { if (is_var(name)) cerror("duplicate variable"); if (nVars == SIZEVART-1) cerror("too many variables"); strcpy(Vars[nVars].name, name); Vars[nVars].value = 0.0; nVars++; }
/* * code for the end of a function * deals with struct return here * The return value is in (or pointed to by) RETREG. */ void efcode(void) { struct symtab *sp; extern int gotnr; TWORD t; NODE *p, *r, *l; int typ, ssz, rno; gotnr = 0; /* new number for next fun */ sp = cftnsp; t = DECREF(sp->stype); if (t != STRTY && t != UNIONTY) return; /* XXX should have one routine for this */ ngpr = nsse = 0; if ((typ = argtyp(t, sp->sdf, sp->sap)) == STRREG || typ == STRCPX) { /* Cast to long pointer and move to the registers */ /* XXX can overrun struct size */ /* XXX check carefully for SSE members */ if ((ssz = tsize(t, sp->sdf, sp->sap)) > SZLONG*2) cerror("efcode1"); if (typ == STRCPX) { t = DOUBLE; rno = XMM0; } else { t = LONG; rno = RAX; } if (ssz > SZLONG) { p = block(REG, NIL, NIL, INCREF(t), 0, 0); regno(p) = RAX; p = buildtree(UMUL, buildtree(PLUS, p, bcon(1)), NIL); ecomp(movtoreg(p, rno+1)); } p = block(REG, NIL, NIL, INCREF(t), 0, 0); regno(p) = RAX; p = buildtree(UMUL, p, NIL); ecomp(movtoreg(p, rno)); } else if (typ == STRMEM) { r = block(REG, NIL, NIL, INCREF(t), sp->sdf, sp->sap); regno(r) = RAX; r = buildtree(UMUL, r, NIL); l = tempnode(stroffset, INCREF(t), sp->sdf, sp->sap); l = buildtree(UMUL, l, NIL); ecomp(buildtree(ASSIGN, l, r)); l = block(REG, NIL, NIL, LONG, 0, 0); regno(l) = RAX; r = tempnode(stroffset, LONG, 0, 0); ecomp(buildtree(ASSIGN, l, r)); } else cerror("efcode"); }
/* Виртуальная машина */ int do_command(unsigned char cop) { double op1, op2; //операнды char name[SIZENAME]; switch(cop) { case CNOP: break; case CPUSH: push(get_value()); break; case CIN: fscanf(vmin, "%lf", &op1); push(op1); break; case COUT: fprintf(vmout, "%g", pull()); break; case CNVAR: get_name(name); add_var(name); break; case CGVAR: get_name(name); push(get_var(name)); break; case CSVAR: get_name(name); set_var(name, pull()); break; case CADD: push(pull()+pull()); break; case CSUB: op1 = pull(); op2 = pull(); push(op2-op1); break; case CMULT: push(pull()*pull()); break; case CDIV: op1 = pull(); op2 = pull(); if (op1==0.0) cerror("divide by zero"); push(op2/op1); break; case CHALT: return 0; default: cerror("undefined command"); } return 1; }
/* * The first six 64-bit arguments are saved in the registers O0 to O5, * which become I0 to I5 after the "save" instruction moves the register * window. Arguments 7 and up must be saved on the stack to %sp+BIAS+176. * * For a pretty picture, see Figure 3-16 in the SPARC Compliance Def 2.4. */ static NODE * moveargs(NODE *p, int *regp, int *stacksize) { NODE *r, *q; if (p->n_op == CM) { p->n_left = moveargs(p->n_left, regp, stacksize); r = p->n_right; } else { r = p; } /* XXX more than six FP args can and should be passed in registers. */ if (*regp > 5 && r->n_op != STARG) { /* We are storing the stack offset in n_rval. */ r = block(FUNARG, r, NIL, r->n_type, r->n_df, r->n_ap); /* Make sure we are appropriately aligned. */ *stacksize = ALIGN(*stacksize, (tlen(r) - 1)); r->n_rval = *stacksize; *stacksize += tlen(r); } else if (r->n_op == STARG) cerror("op STARG in moveargs"); else { q = block(REG, NIL, NIL, r->n_type, r->n_df, r->n_ap); /* * The first six non-FP arguments go in the registers O0 - O5. * Float arguments are stored in %fp1, %fp3, ..., %fp29, %fp31. * Double arguments are stored in %fp0, %fp2, ..., %fp28, %fp30. * A non-fp argument still increments register, eg. * test(int a, int b, float b) * takes %o0, %o1, %fp5. */ if (q->n_type == FLOAT) q->n_rval = F0 + (*regp++ * 2) + 1; else if (q->n_type == DOUBLE) q->n_rval = D0 + *regp++; else if (q->n_type == LDOUBLE) cerror("long double support incomplete"); else q->n_rval = O0 + (*regp)++; r = buildtree(ASSIGN, q, r); } if (p->n_op == CM) { p->n_right = r; return p; } return r; }
void t2k2(vcsect* g, int * nv, cvertex * vl) { int i,k, ne, en=0, maxnv=*nv; int maptar[2*maxvert][MAXVALENCE]; /* Transfer Taranov's representation of graph to Kryukov's representation */ /* - 07/01/90 */ for(i=0; i<2*maxvert; i++) for(k=0; k<MAXVALENCE; k++) maptar[i][k]=0; *nv=0; for(i=0; i<g->sizet; i++) if (typev(g->vertlist[i],g->valence[i]) != zv) { if(*nv>= maxnv) cerror(251,"To many vertices"); vl[*nv].e[0]=0; vl[*nv].e[1]=0; vl[*nv].e[2]=0; vl[*nv].vt = typev(g->vertlist[i],g->valence[i]); for (k=0, ne=0; ne<g->valence[i] ; ne++) { int dim= prtclbase[g->vertlist[i][ne].partcl-1].cdim; if(dim!=1) { int l=maptar[i][ne]; if(!l) { l = ++en; maptar[i][ne] = l; maptar[g->vertlist[i][ne].link.vno] [g->vertlist[i][ne].link.edno]=l; } if (vl[*nv].vt != g3 && vl[*nv].vt != g2) switch (dim) { case 8: vl[*nv].e[0]=l; break; case -3: vl[*nv].e[1]=l; break; case 3: vl[*nv].e[2]=l; break; default: cerror(252,"t2k - invalid particle color"); } else vl[*nv].e[k++] = l; } } (*nv)++; } }
int libevent_client_test(int argc, char*argv[]) { int fd; struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; if(argc<3) { port = 8888; }else { port = atoi(argv[2]); } sin.sin_port = htons(port); if(argc<2) { strcpy(addr, argv[1]); if (inet_pton(AF_INET, addr, &(sin.sin_addr) )<0) { struct hostent *psh; psh=gethostbyname(addr); if(psh!=NULL) inet_pton(AF_INET, psh->h_addr, &(sin.sin_addr) ); else cerror("inet_pton"); } } if((fd=socket(AF_INET, SOCK_STREAM, 0))<0) cerror("socket"); if(connect(fd, (struct sockaddr*)&sin, sizeof(sin))<0 ) cerror("sonnect"); if( (nlen = write(fd,msg, strlen(msg)))<0 ) cerror("write"); if( (nlen = read(fd,msg, strlen(msg)))<0 ) cerror("read"); msg[nlen]='\0'; printf("msg: %s\n", msg); return 0; }
void hopcode( f, o ){ /* output the appropriate string from the above table */ register struct hoptab *q; for( q = ioptab; q->opmask>=0; ++q ){ if( q->opmask == o ){ printf( "%s", q->opstring ); /* tbl if( f == 'F' ) printf( "e" ); else if( f == 'D' ) printf( "d" ); tbl */ /* tbl */ switch( f ) { case 'L': case 'W': case 'B': case 'D': case 'F': printf("%c", tolower(f)); break; } /* tbl */ return; } } cerror( "no hoptab for %s", opst[o] ); }
/* * code for the end of a function * deals with struct return here */ void efcode() { NODE *p, *q; int sz; if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN) return; cerror("efcode"); /* address of return struct is in eax */ /* create a call to memcpy() */ /* will get the result in eax */ p = block(REG, NIL, NIL, CHAR+PTR, 0, 0); // p->n_rval = EAX; q = block(OREG, NIL, NIL, CHAR+PTR, 0, 0); // q->n_rval = EBP; q->n_lval = 8; /* return buffer offset */ p = block(CM, q, p, INT, 0, 0); sz = (tsize(STRTY, cftnsp->sdf, cftnsp->ssue)+SZCHAR-1)/SZCHAR; p = block(CM, p, bcon(sz), INT, 0, 0); p->n_right->n_name = ""; p = block(CALL, bcon(0), p, CHAR+PTR, 0, 0); p->n_left->n_name = "memcpy"; p = clocal(p); send_passt(IP_NODE, p); }
/* * AMD64 parameter classification. */ static int argtyp(TWORD t, union dimfun *df, struct attr *ap) { int cl = 0; if (t <= ULONG || ISPTR(t) || t == BOOL) { cl = ngpr < 6 ? INTEGER : INTMEM; } else if (t == FLOAT || t == DOUBLE || t == FIMAG || t == IMAG) { cl = nsse < 8 ? SSE : SSEMEM; } else if (t == LDOUBLE || t == LIMAG) { cl = X87; /* XXX */ } else if (t == STRTY || t == UNIONTY) { int sz = tsize(t, df, ap); if (sz <= 2*SZLONG && attr_find(ap, ATTR_COMPLEX) != NULL) { cl = nsse < 7 ? STRCPX : STRMEM; } else if (sz > 2*SZLONG || ((sz+SZLONG)/SZLONG)+ngpr > 6 || attr_find(ap, GCC_ATYP_PACKED) != NULL) cl = STRMEM; else cl = STRREG; } else cerror("FIXME: classify"); return cl; }
/* * code for the end of a function * deals with struct return here */ void efcode(void) { NODE *p, *q; // int sz; #if 0 /* restore ac3 */ p = block(REG, 0, 0, INT, 0, 0); regno(p) = 3; q = tempnode(ac3temp, INT, 0, 0); ecomp(buildtree(ASSIGN, p, q)); #endif if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN) return; cerror("efcode"); /* address of return struct is in eax */ /* create a call to memcpy() */ /* will get the result in eax */ p = block(REG, NIL, NIL, CHAR+PTR, 0, 0); // p->n_rval = EAX; q = block(OREG, NIL, NIL, CHAR+PTR, 0, 0); // q->n_rval = EBP; q->n_lval = 8; /* return buffer offset */ p = block(CM, q, p, INT, 0, 0); // sz = (tsize(STRTY, cftnsp->sdf, cftnsp->ssue)+SZCHAR-1)/SZCHAR; // p = block(CM, p, bcon(sz), INT, 0, 0); p->n_right->n_name = ""; p = block(CALL, bcon(0), p, CHAR+PTR, 0, 0); p->n_left->n_name = "memcpy"; p = clocal(p); send_passt(IP_NODE, p); }
static int toolarge(TWORD t, CONSZ con) { U_CONSZ ucon = con; switch (t) { case ULONG: case LONG: case ULONGLONG: case LONGLONG: break; /* cannot be too large */ #define SCHK(i) case i: if (con > MAX_##i || con < MIN_##i) return 1; break #define UCHK(i) case i: if (ucon > MAX_##i) return 1; break SCHK(INT); SCHK(SHORT); case BOOL: SCHK(CHAR); UCHK(UNSIGNED); UCHK(USHORT); UCHK(UCHAR); default: cerror("toolarge"); } return 0; }
/* push character */ static void nmch(int c) { if (nmptr >= MAXNM) cerror("Too long mangled name"); nmblk[nmptr++] = c; }
/* * Put all builtin functions into the global symbol table. */ void builtin_init() { const struct bitable *bt; NODE *p = block(TYPE, 0, 0, 0, 0, 0); struct symtab *sp; int i, d_debug; d_debug = ddebug; ddebug = 0; for (i = 0; i < (int)(sizeof(bitable)/sizeof(bitable[0])); i++) { bt = &bitable[i]; if ((bt->flags & BTGNUONLY) && xgnu99 == 0 && xgnu89 == 0) continue; /* not in c99 universe, at least for now */ sp = lookup(addname(bt->name), 0); if (bt->rt == 0 && (bt->flags & BTNORVAL) == 0) cerror("function '%s' has no return type", bt->name); p->n_type = INCREF(bt->rt) + (FTN-PTR); p->n_df = memset(permalloc(sizeof(union dimfun)), 0, sizeof(union dimfun)); p->n_sp = sp; defid(p, EXTERN); sp->soffset = i; sp->sflags |= SBUILTIN; } nfree(p); ddebug = d_debug; }
static int scanch(void) { int c, c2; c = next(); if ('\\' == c) { switch (c = next()) { case 'a': return '\a'; case 'b': return '\b'; case 'f': return '\f'; case 'n': return '\n'; case 'r': return '\r'; case 't': return '\t'; case 'v': return '\v'; case '\\': return '\\'; case '"': return '"' | 256; case '\'': return '\''; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': for (c2 = 0; isdigit(c) && c < '8'; c = next()) c2 = c2 * 8 + (c - '0'); putback(c); return c2; case 'x': return hexchar(); default: cerror("unknown escape sequence: %s", c); return ' '; } } else { return c; } }
static int scanint(int c) { int val, radix, k, i = 0; val = 0; radix = 10; if ('0' == c) { Text[i++] = '0'; if ((c = next()) == 'x') { radix = 16; Text[i++] = c; c = next(); } else { radix = 8; } } while ((k = chrpos("0123456789abcdef", tolower(c))) >= 0) { Text[i++] = c; if (k >= radix) cerror("invalid digit in integer literal: %s", c); val = val * radix + k; c = next(); } putback(c); Text[i] = 0; return val; }
NODE * getlr(NODE *p, int c) { /* return the pointer to the left or right side of p, or p itself, depending on the optype of p */ switch (c) { case '1': case '2': case '3': case 'D': if (c == 'D') c = 0; else c -= '0'; if (resc[c].n_op == FREE) comperr("getlr: free node"); return &resc[c]; case 'L': return( optype( p->n_op ) == LTYPE ? p : p->n_left ); case 'R': return( optype( p->n_op ) != BITYPE ? p : p->n_right ); } cerror( "bad getlr: %c", c ); /* NOTREACHED */ return NULL; }
void push(double num) { if(Top<SIZESTK) { Stack[Top++]=num; } else cerror("Stack full"); }
/* * cause the alignment to become a multiple of n */ void defalign(int n) { n = ispow2(n / SZCHAR); if (n == -1) cerror("defalign: n != 2^i"); printf("\t.p2align %d\n", n); }
static int leb128(int d) { if (d > 127) cerror("FIXME: leb128 > 127"); p1b(d); return 1; }
void die(char *s) { error++; errprint(); cerror(s); Bputc(&bout, '\n'); exits("error"); }
/* работа с переменными */ double get_var(char* name) { int i; for (i=0; i<nVars; i++) if (strcmp(name, Vars[i].name)==0) return Vars[i].value; cerror("variable not found to get"); return 0.0; }
/* * print accumulated error reports */ void errprint(void) { Bflush(&bout); for(; err != 0; err = err->e_nextp) { cerror(err->e_mess); fprint(2, "\n"); } }
double pull(void) { if(Top!=0) { Top--; return Stack[Top]; } else cerror("Stack empty"); return 0.0; }
NODE * talloc(){ register NODE *p, *q; q = lastfree; for( p = TNEXT(q); p!=q; p= TNEXT(p)) if( p->in.op ==FREE ) return(lastfree=p); cerror( 208 ); /* out of tree space; simplify expression */ /* NOTREACHED */ }
static void errprint() /* print accumulated error reports */ { (void) fflush(stdout); for (; Err != NULL; Err = Err->e_nextp) { cerror(Err->e_mess); (void) putc('\n', stderr); } done(); }