#include "supp.h" #include "opt.h" static char FILE_[]=__FILE__; #ifndef HAVE_EXT_TYPES char *typname[]={"strange","char","short","int","long","long long", "float","double","long double","void", "pointer","array","struct","union","enum","function", "bool","vector"}; #endif char *storage_class_name[]={"strange","auto","register","static","extern","typedef"}; char *ename[]={"strange","sequence","move","set+","set-","set*","set/","set%", "set&","set^","set|","set<<","set>>","?:","lor","land","or", "eor","and","eq","neq","lt","le","gt","ge","lsl", "lsr","add","sub","mul","div","mod","negate", "not","preinc","postinc","predec","postdec","neg", "dref-pointer","address-of","cast","call","index", "dref-struct-pointer","dref-struct","identifier","constant", "string","member", "convert","convert-short","convert-int","convert-long", "convert-float","convert-double","convert-void","convert-pointer", "convert-uchar","convert-ushort","convert-uint","convert-ulong", "address-of-array","first-element-of-array","pmult", "allocreg","freereg","pconstant","test","label","beq","bne", "blt","bge","ble","bgt","bra","compare","push","pop", "address-of-struct","add-int-to-pointer","sub-int-from-pointer", "sub-pointer-from-pointer","push-reg","pop-reg","pop-args", "save-regs","restore-regs","identifier-label","dc","align", "colon","get-return","set-return","move-from-reg","move-to-reg", "nop","bitfield"}; char *empty=""; zchar vchar; zuchar vuchar; zshort vshort; zushort vushort; zint vint; zuint vuint; zlong vlong; zulong vulong; zllong vllong; zullong vullong; zmax vmax; zumax vumax; zfloat vfloat; zdouble vdouble; zldouble vldouble; union atyps gval; #ifndef DEBUG int DEBUG; #endif int label; int regs[MAXR+1],regused[MAXR+1],simple_scratch[MAXR+1]; struct Var *regsv[MAXR+1]; int goto_used; int ic_count; zmax max_offset; int function_calls,vlas; int coloring; int dmalloc; int disable; int multiple_ccs; int lastlabel,return_label; int only_inline; struct IC *err_ic; long maxoptpasses=10; long optflags; int optsize,optspeed,unroll_all,stack_check; int cross_module,final,no_emit; int debug_info; long inline_size=100; long inline_depth=1; long unroll_size=200; int fp_assoc,noaliasopt,noitra; char *filename; struct IC *first_ic,*last_ic; int float_used; bvtype regs_modified[RSIZE/sizeof(bvtype)]; /* Das haette ich gern woanders */ struct Var *vl0,*vl1,*vl2,*vl3; int align_arguments=1; zmax stackalign; int misracheck,misraversion,misracomma,misratok; int pack_align; int short_push; int default_unsigned; char *emit_buffer[EMIT_BUF_DEPTH]; char *emit_p; int emit_f,emit_l; int no_inline_peephole; struct Typ *new_typ(void) /* Erzeigt neuen (leeren) Typ. */ { struct Typ *new=mymalloc(TYPS); new->flags=0; new->next=0; new->exact=0; new->attr=0; new->dsize=0; new->reg=0; #ifdef HAVE_ECPP /* removed */ #endif return new; } struct Typ *clone_typ(struct Typ *old) /* Erzeugt Kopie eines Typs und liefert Zeiger auf Kopie. */ { struct Typ *new; if(!old) return 0; new=new_typ(); *new=*old; if(old->attr){ new->attr=mymalloc(strlen(old->attr)+1); strcpy(new->attr,old->attr); } if(new->next) new->next=clone_typ(new->next); return new; } struct Var *new_var(void) { struct Var *new=mymalloc(sizeof(*new)); new->clist=0; new->vtyp=0; new->storage_class=0; new->reg=0; new->vattr=0; new->next=0; new->flags=0; new->fi=0; new->nesting=0; new->filename=0; new->line=0; new->dfilename=0; new->dline=0; new->description=0; new->tunit=0; new->offset=l2zm(0L); new->identifier=0; #ifdef HAVE_TARGET_ATTRIBUTES new->tattr=0; #endif #ifdef ALEX_REG new->iRegCopyNr = -1; new->iRegCopyNrHc12V = -1; #endif return new; } struct IC *new_IC(void) { struct IC *p=mymalloc(ICS); p->change_cnt=0; p->use_cnt=0; p->call_cnt=0; p->arg_cnt=0; p->use_list=0; p->change_list=0; p->call_list=0; p->arg_list=0; p->line=0; p->file=0; p->flags=0; p->q1.flags=p->q2.flags=p->z.flags=0; p->q1.am=p->q2.am=p->z.am=0; p->q1.val.vmax=p->q2.val.vmax=p->z.val.vmax=l2zm(0L); p->savedsp=0; p->typf=p->typf2=0; #ifdef ALEX_REG p->iZWebIndex = -1; p->iQ1WebIndex = -1; p->iQ2WebIndex = -1; p->pFlow = NULL; #endif /* GC_RALLOC */ return p; } /* (partially) clones an IC list */ struct IC *clone_ic(struct IC *p) { struct IC *new,*first,*last; first=last=new=0; while(p){ new=mymalloc(sizeof(*new)); *new=*p; p->copy=new; if(new->code==CALL){ int i; new->arg_list=mymalloc(sizeof(*new->arg_list)*new->arg_cnt); for(i=0;iarg_cnt;i++) new->arg_list[i]=p->arg_list[i]->copy; } new->prev=last; new->next=0; if(!first) first=new; if(last) last->next=new; last=new; p=p->next; } return first; } void free_IC(struct IC *p) /* Gibt IC-Liste inkl. Typen frei. */ { struct IC *merk; if(DEBUG&1) printf("free_IC()\n"); while(p){ /*if(p->q1.am&&!p->q1.flags) ierror(0); if(p->q2.am&&!p->q2.flags) ierror(0); if(p->z.am&&!p->z.flags) ierror(0);*/ if(p->q1.am) free(p->q1.am); if(p->q2.am) free(p->q2.am); if(p->z.am) free(p->z.am); if(p->code==CALL) free(p->arg_list); merk=p->next; free(p); p=merk; } } void move_IC(struct IC *after,struct IC *p) { if(p->prev) p->prev->next=p->next; else first_ic=p->next; if(p->next) p->next->prev=p->prev; else last_ic=p->prev; insert_IC(after,p); } void remove_IC(struct IC *p) /* Entfernt IC p aus Liste. */ { if(p->prev) p->prev->next=p->next; else first_ic=p->next; if(p->next) p->next->prev=p->prev; else last_ic=p->prev; if(p->q1.am) free(p->q1.am); if(p->q2.am) free(p->q2.am); if(p->z.am) free(p->z.am); free(p); } void freetyp(struct Typ *p) /* Gibt eine Typ-Liste frei, aber keine struct_declaration oder so. */ { int f;struct Typ *merk; if(DEBUG&8){printf("freetyp: ");prd(stdout,p);printf("\n");} while(p){ merk=p->next; f=p->flags&NQ; if(merk&&!ISARRAY(f)&&!ISPOINTER(f)&&!ISFUNC(f)&&!ISVECTOR(f)) ierror(0); free(p->attr); free(p); p=merk; } } #ifndef HAVE_TGT_FALIGN zmax falign(struct Typ *t) /* Liefert Alignment eines Typs. Funktioniert im Gegensatz zum */ /* align[]-Array auch mit zusammengesetzten Typen. */ { int i,f; zmax al,alt; f=t->flags&NQ; if(ISVECTOR(f)) return szof(t); al=align[f]; if(ISSCALAR(f)) return al; if(ISARRAY(f)){ do{ t=t->next; f=t->flags&NQ; }while(ISARRAY(f)||ISVECTOR(f)); alt=falign(t); if(zmleq(al,alt)) return alt; else return al; } if(ISUNION(f)||ISSTRUCT(f)){ if(!t->exact) ierror(0); for(i=0;iexact->count;i++){ alt=(*t->exact->sl)[i].align; if(!zmleq(alt,al)) al=alt; } } return al; } #endif /* check, whether t is a variable length array */ int is_vlength(struct Typ *t) { if(!ISARRAY(t->flags)) return 0; if(t->dsize) return 1; else return is_vlength(t->next); } /* calculate size of a variable length array */ struct Var *vlength_szof(struct Typ *t) { struct IC *new;struct Typ *nt; if(!ISARRAY(t->flags)) ierror(0); new=new_IC(); new->code=MULT; new->typf=HAVE_INT_SIZET?(UNSIGNED|INT):(UNSIGNED|LONG); if(t->dsize){ new->q1.flags=VAR; new->q1.v=t->dsize; new->q1.val.vmax=l2zm(0L); }else{ new->q1.flags=KONST; #if HAVE_INT_SIZET new->q1.val.vuint=zum2zui(zm2zum(t->size)); #else new->q1.val.vulong=zum2zul(zm2zum(t->size)); #endif } new->z.flags=VAR; nt=new_typ(); nt->flags=new->typf; new->z.v=add_tmp_var(nt); new->z.val.vmax=l2zm(0L); if(is_vlength(t->next)){ new->q2.flags=VAR; new->q2.v=vlength_szof(t->next); new->q2.val.vmax=l2zm(0L); }else{ new->q2.flags=KONST; #if HAVE_INT_SIZET new->q2.val.vuint=zum2zui(zm2zum(szof(t->next))); #else new->q2.val.vulong=zum2zul(zm2zum(szof(t->next))); #endif } add_IC(new); return new->z.v; } /* return the type of a d-dim vector of base type x */ int mkvec(int x,int d) { int t=x&NQ,r; if(d!=2&&d!=3&&d!=4&&d!=8&&d!=16) ierror(0); switch(t){ case BOOL: r=VECBOOL;break; case CHAR: r=VECCHAR;break; case SHORT: r=VECSHORT;break; case INT: r=VECINT;break; case LONG: r=VECLONG;break; case FLOAT: r=VECFLOAT;break; default: ierror(0); } return (r+d-1)|(x&~NQ); } /* return the base type of a vector */ int VECTYPE(int x) { int t=x&NQ,r=0; if(t>=VECBOOL&&t<=VECBOOL+MAXVECDIM) r=BOOL; if(t>=VECCHAR&&t<=VECCHAR+MAXVECDIM) r=CHAR; if(t>=VECSHORT&&t<=VECSHORT+MAXVECDIM) r=SHORT; if(t>=VECINT&&t<=VECINT+MAXVECDIM) r=INT; if(t>=VECLONG&&t<=VECLONG+MAXVECDIM) r=LONG; if(t>=VECFLOAT&&t<=VECFLOAT+MAXVECDIM) r=FLOAT; if(!r) ierror(0); return r|(x&~NQ); } #ifndef HAVE_TGT_SZOF zmax szof(struct Typ *t) /* Liefert die benoetigte Groesse eines Typs in Bytes. */ { int i=t->flags&NQ,j;zmax size,m; #ifdef HAVE_ECPP /* removed */ #endif if(ISSCALAR(i)) return sizetab[i]; if(ISARRAY(i)){ if(is_vlength(t)) return sizetab[POINTER_TYPE(t->next)]; size=zmmult((t->size),szof(t->next)); m=align[ARRAY]; return zmmult(zmdiv(zmadd(size,zmsub(m,l2zm(1L))),m),m); /* align */ } if(ISVECTOR(i)){ zmax dim=VECDIM(i); if(zmeqto(dim,l2zm(3L))) dim=l2zm(4L); return zmmult(dim,sizetab[VECTYPE(i)&NQ]); } if(ISUNION(i)){ for(j=0,size=l2zm(0L);jexact->count;j++){ m=szof((*t->exact->sl)[j].styp); if(zmeqto(m,l2zm(0L))) return l2zm(0L); if(!zmleq(m,size)) size=m; } m=falign(t); return zmmult(zmdiv(zmadd(size,zmsub(m,l2zm(1L))),m),m); /* align */ } if(ISSTRUCT(i)){ size=l2zm(0L); #ifdef HAVE_ECPP /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ #endif for(j=0;jexact->count;j++){ struct Typ *h=(*t->exact->sl)[j].styp; if((*t->exact->sl)[j].bfoffset<=0){ m=(*t->exact->sl)[j].align; #ifdef HAVE_ECPP /* removed */ #endif if(zmeqto(m,l2zm(0L))) {prd(stdout,h);ierror(0);} size=zmmult(zmdiv(zmadd(size,zmsub(m,l2zm(1L))),m),m); m=szof(h); /*if(zmeqto(m,l2zm(0L))) return l2zm(0L);*/ size=zmadd(size,m); } } m=falign(t); return zmmult(zmdiv(zmadd(size,zmsub(m,l2zm(1L))),m),m); /* align */ } return sizetab[i]; } zmax struct_offset(struct struct_declaration *sd,const char *identifier) { int i=0,intbitfield=-1;zmax offset=l2zm(0),al; while(icount&&strcmp((*sd->sl)[i].identifier,identifier)){ if((*sd->sl)[i].bfoffset>=0){ if(i+1count&&(*sd->sl)[i+1].bfoffset>0){ i++; continue; } } al=(*sd->sl)[i].align; offset=zmmult(zmdiv(zmadd(offset,zmsub(al,l2zm(1L))),al),al); offset=zmadd(offset,szof((*sd->sl)[i].styp)); i++; } if(i>=sd->count) {error(23,identifier);return l2zm(0L);} al=(*sd->sl)[i].align; offset=zmmult(zmdiv(zmadd(offset,zmsub(al,l2zm(1L))),al),al); return offset; } #ifdef HAVE_ECPP /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ #endif #endif #ifndef HAVE_TGT_PRINTVAL void printval(FILE *f,union atyps *p,int t) /* Gibt atyps aus. */ { t&=NU; if(t==CHAR){fprintf(f,"C");vmax=zc2zm(p->vchar);printzm(f,vmax);} if(t==(UNSIGNED|CHAR)){fprintf(f,"UC");vumax=zuc2zum(p->vuchar);printzum(f,vumax);} if(t==SHORT){fprintf(f,"S");vmax=zs2zm(p->vshort);printzm(f,vmax);} if(t==(UNSIGNED|SHORT)){fprintf(f,"US");vumax=zus2zum(p->vushort);printzum(f,vumax);} if(t==FLOAT){fprintf(f,"F");vldouble=zf2zld(p->vfloat);printzld(f,vldouble);} if(t==DOUBLE){fprintf(f,"D");vldouble=zd2zld(p->vdouble);printzld(f,vldouble);} if(t==LDOUBLE){fprintf(f,"LD");printzld(f,p->vldouble);} if(t==INT){fprintf(f,"I");vmax=zi2zm(p->vint);printzm(f,vmax);} if(t==(UNSIGNED|INT)){fprintf(f,"UI");vumax=zui2zum(p->vuint);printzum(f,vumax);} if(t==LONG){fprintf(f,"L");vmax=zl2zm(p->vlong);printzm(f,vmax);} if(t==(UNSIGNED|LONG)){fprintf(f,"UL");vumax=zul2zum(p->vulong);printzum(f,vumax);} if(t==LLONG){fprintf(f,"LL");vmax=zll2zm(p->vllong);printzm(f,vmax);} if(t==(UNSIGNED|LLONG)){fprintf(f,"ULL");vumax=zull2zum(p->vullong);printzum(f,vumax);} if(t==MAXINT){fprintf(f,"M");printzm(f,p->vmax);} if(t==(UNSIGNED|MAXINT)){fprintf(f,"UM");printzum(f,p->vumax);} /*FIXME*/ if(t==POINTER){fprintf(f,"P");vumax=zul2zum(p->vulong);printzum(f,vumax);} } void emitval(FILE *f,union atyps *p,int t) /* Gibt atyps aus. */ { t&=NU; if(t==CHAR){vmax=zc2zm(p->vchar);emitzm(f,vmax);} if(t==(UNSIGNED|CHAR)){vumax=zuc2zum(p->vuchar);emitzum(f,vumax);} if(t==SHORT){vmax=zs2zm(p->vshort);emitzm(f,vmax);} if(t==(UNSIGNED|SHORT)){vumax=zus2zum(p->vushort);emitzum(f,vumax);} if(t==FLOAT){vldouble=zf2zld(p->vfloat);emitzld(f,vldouble);} if(t==DOUBLE){vldouble=zd2zld(p->vdouble);emitzld(f,vldouble);} if(t==LDOUBLE){emitzld(f,p->vldouble);} if(t==INT){vmax=zi2zm(p->vint);emitzm(f,vmax);} if(t==(UNSIGNED|INT)){vumax=zui2zum(p->vuint);emitzum(f,vumax);} if(t==LONG){vmax=zl2zm(p->vlong);emitzm(f,vmax);} if(t==(UNSIGNED|LONG)){vumax=zul2zum(p->vulong);emitzum(f,vumax);} if(t==LLONG){vmax=zll2zm(p->vllong);emitzm(f,vmax);} if(t==(UNSIGNED|LLONG)){vumax=zull2zum(p->vullong);emitzum(f,vumax);} if(t==MAXINT){emitzm(f,p->vmax);} if(t==(UNSIGNED|MAXINT)){emitzum(f,p->vumax);} /*FIXME*/ if(t==POINTER){vumax=zul2zum(p->vulong);emitzum(f,vumax);} } #endif void pric2(FILE *f,struct IC *p) /* Gibt ein IC aus. */ { if(p->code>NOP) ierror(0); if(p->next&&p->next->prev!=p) ierror(0); if(p->code>=LABEL&&p->code<=BRA){ if(p->code==LABEL) fprintf(f,"L%d",p->typf); else{ fprintf(f,"\t%s L%d",ename[p->code],p->typf); if(p->q1.flags){ fprintf(f,",");probj(f,&p->q1,0);} } if(p->code==LABEL&&(p->flags&LOOP_COND_TRUE)) fprintf(f," (while-loop)"); if(p->code==BRA&&(p->flags&LOOP_COND_TRUE)) fprintf(f," (to-loop-test)"); }else{ fprintf(f,"\t%s ",ename[p->code]); if(p->typf&VOLATILE) fprintf(f,"volatile "); if(p->typf&CONST) fprintf(f,"const "); if(p->typf&UNSIGNED) fprintf(f,"unsigned "); if(p->typf){ if(ISVECTOR(p->typf)) fprintf(f,"%s%d ",typname[VECTYPE(p->typf)&NQ],VECDIM(p->typf)); else fprintf(f,"%s ",typname[p->typf&NQ]); } probj(f,&p->q1,q1typ(p)); if(p->q2.flags){fprintf(f,",");probj(f,&p->q2,q2typ(p));} if(p->z.flags){fprintf(f,"->");probj(f,&p->z,ztyp(p));} if(p->code==ASSIGN||p->code==PUSH||p->code==POP||p->code==CALL) fprintf(f," size=%ld",zm2l(p->q2.val.vmax)); if((p->code==SAVEREGS||p->code==RESTOREREGS)&&p->q1.reg) fprintf(f," except %s",regnames[p->q1.reg]); if(p->code==CONVERT) fprintf(f," from %s%s",(p->typf2&UNSIGNED)?"unsigned ":"",typname[p->typf2&NQ]); if(p->code==LSHIFT||p->code==RSHIFT) fprintf(f," shift-type %s%s",(p->typf2&UNSIGNED)?"unsigned ":"",typname[p->typf2&NQ]); if(p->code==ADDI2P||p->code==SUBIFP||p->code==SUBPFP||p->code==ADDRESS) fprintf(f," ptype=%s%s",(p->typf2&UNSIGNED)?"unsigned ":"",typname[p->typf2&NQ]); if(p->code==ASSIGN||p->code==PUSH) if(p->typf2) fprintf(f," align=%d\n",p->typf2); } if(p->code==CALL){ fprintf(f," =>"); if(p->call_cnt==0) fprintf(f,"(unknown)"); else{ int i; for(i=0;icall_cnt;i++) fprintf(f," %s",p->call_list[i].v->identifier); } } fprintf(f,"\n"); #if 0 if(p->code==CALL){ int i; fprintf(f,"c=%p\n",p); for(i=0;iarg_cnt;i++){ fprintf(f,"%p!\n",p->arg_list[i]); fprintf(f,"%02d:",i); pric2(f,p->arg_list[i]); } } #endif } void pric(FILE *f,struct IC *p) /* Gibt IC-Liste auf dem Bildschirm aus. */ { while(p){ pric2(f,p); /* if(p->q1.am||p->q2.am||p->z.am) ierror(0);*/ p=p->next; } } void printzm(FILE *f,zmax x) /* Konvertiert zmax nach ASCII. */ /* Basiert noch einigermassen auf */ /* Zweierkomplementdarstellung (d.h. -MIN>MAX). */ /* Ausserdem muss max(abs(max))<=max(unsigned max). */ { zmax zm;zumax zum; zm=l2zm(0L); if(zmleq(x,zm)&&!zmeqto(x,zm)){ fprintf(f,"-");zm=zum2zm(t_max(MAXINT)); if(zmleq(x,zmsub(l2zm(0L),zm))&&!zmeqto(x,zmsub(l2zm(0L),zm))){ /* aufpassen, da -x evtl. >LONG_MAX */ zum=t_max(MAXINT); x=zmadd(x,zm); }else zum=ul2zum(0UL); x=zmsub(l2zm(0L),x); vumax=zm2zum(x); zum=zumadd(zum,vumax); }else zum=zm2zum(x); printzum(f,zum); } void printzum(FILE *f,zumax x) /* Konvertiert zumax nach ASCII. */ { zumax zum;unsigned long l; zum=ul2zum(10UL); if(!zumeqto(zumdiv(x,zum),ul2zum(0UL))) printzum(f,zumdiv(x,zum)); zum=zummod(x,zum);l=zum2ul(zum); fprintf(f,"%c",(int)(l+'0')); } void printzld(FILE *f,zldouble x) /* Konvertiert zdouble nach ASCII, noch nicht fertig. */ { fprintf(f,"fp-constant"); } void emitzm(FILE *f,zmax x) /* Konvertiert zmax nach ASCII. */ /* Basiert noch einigermassen auf */ /* Zweierkomplementdarstellung (d.h. -MIN>MAX). */ /* Ausserdem muss max(abs(max))<=max(unsigned max). */ { zmax zm;zumax zum; zm=l2zm(0L); if(zmleq(x,zm)&&!zmeqto(x,zm)){ emit(f,"-");zm=zum2zm(t_max(MAXINT)); if(zmleq(x,zmsub(l2zm(0L),zm))&&!zmeqto(x,zmsub(l2zm(0L),zm))){ /* aufpassen, da -x evtl. >LONG_MAX */ zum=t_max(MAXINT); x=zmadd(x,zm); }else zum=ul2zum(0UL); x=zmsub(l2zm(0L),x); vumax=zm2zum(x); zum=zumadd(zum,vumax); }else zum=zm2zum(x); emitzum(f,zum); } void emitzum(FILE *f,zumax x) /* Konvertiert zumax nach ASCII. */ { zumax zum;unsigned long l; zum=ul2zum(10UL); if(!zumeqto(zumdiv(x,zum),ul2zum(0UL))) emitzum(f,zumdiv(x,zum)); zum=zummod(x,zum);l=zum2ul(zum); emit(f,"%c",(int)(l+'0')); } void emitzld(FILE *f,zldouble x) /* Konvertiert zdouble nach ASCII, noch nicht fertig. */ { emit(f,"fp-constant"); } static struct memblock {struct memblock *next;void *p;} *first_mb; static void add_mb(void *p) { struct memblock *mb_second=first_mb; struct memblock *mb=malloc(sizeof(*mb)); if(!mb){ error(12); raus(); } first_mb=mb; mb->next=mb_second; mb->p=p; } static void remove_mb(void *p) { struct memblock *mb_prev=0; struct memblock *mb=first_mb; while(mb){ if(mb->p==p){ if(mb_prev==0) first_mb=mb->next; else mb_prev->next=mb->next; (free)(mb); return; } mb_prev=mb; mb=mb->next; } ierror(0); } void *mymalloc(size_t size) /* Allocate memory and quit on failure. */ { void *p; if(dmalloc) size+=sizeof(size); else if(size==0) /* Not very nice, but simplest way to avoid a failure when size==0. */ size=1; if(!(p=malloc(size))){ error(12); raus(); } if(DEBUG&32768){ printf("malloc %p (s=%lu)\n",p,(unsigned long)size); fflush(stdout); } if(DEBUG&65536) add_mb(p); if(dmalloc){ *(size_t *)p=size; p=((char *)p)+sizeof(size); memset(p,0xaa,size-sizeof(size)); } return p; } void *myrealloc(void *p,size_t size) /* Reallocate memory and quit on failure. */ { void *new; if(!p) return mymalloc(size); if(dmalloc){ size+=sizeof(size); new=realloc(((char *)p)-sizeof(size),size); if(!new){ error(12); raus(); } if(DEBUG&32768){ printf("realloc %p to %p (s=%lu)\n",p,new,(unsigned long)size); fflush(stdout); } if(DEBUG&65536){ remove_mb(p); add_mb(new); } *(size_t *)new=size; new=((char *)new)+sizeof(size); return new; }else{ new=realloc(p,size); if(!new){ error(12); raus(); } if(DEBUG&32768){ printf("realloc %p to %p (s=%lu)\n",p,new,(unsigned long)size); fflush(stdout); } if(DEBUG&65536){ remove_mb(p); add_mb(new); } return new; } } void myfree(void *p) { if(p&&dmalloc){ p=((char*)p)-sizeof(size_t); memset(p,0xbb,*(size_t *)(p)); } if(DEBUG&32768){ printf("free %p\n",p); fflush(stdout); } if((DEBUG&65536)&&p) remove_mb(p); (free)(p); /* supp.h has #define free(x) myfree(x) */ } char *mystrdup(char *p) { char *new=mymalloc(strlen(p)+1); strcpy(new,p); return new; } /* Testet, ob zwei objs dieselben Register belegen. */ int collides(struct obj *x,struct obj *y) { int x1,x2,y1,y2; if(!(x->flags®)||!(y->flags®)) return 0; if(reg_pair(x->reg,&rp)){ x1=rp.r1;x2=rp.r2; }else{ x1=x->reg;x2=-1; } if(reg_pair(y->reg,&rp)){ y1=rp.r1;y2=rp.r2; }else{ y1=y->reg;y2=-2; } if(x1==y1||x1==y2||x2==y1||x2==y2) return 1; else return 0; } /* Versucht, ein IC so zu drehen, dass q2 und z kein gemeinsames */ /* Register belegen. Liefert Null, wenn das nicht moeglich ist. */ int switch_IC(struct IC *p) { int c; struct obj o; if(!collides(&p->q2,&p->z)) return 1; c=p->code; if((cAND)&&c!=ADD&&c!=MULT&&c!=ADDI2P) return 0; if(c==ADDI2P&&must_convert(q1typ(p),q2typ(p),0)) return 0; if(collides(&p->q1,&p->z)) return 0; o=p->q2;p->q2=p->q1;p->q1=o; return 1; } void probj(FILE *f,struct obj *p,int t) /* Gibt Objekt auf Bildschirm aus. */ { if(p->am){ fprintf(f,"[tgt-addressing-mode]");return;} if(p->flags&DREFOBJ){ fprintf(f,"(["); if(p->dtyp&CONST) fprintf(f,"const "); if(p->dtyp&VOLATILE) fprintf(f,"volatile "); fprintf(f,"%s]",typname[p->dtyp&NQ]); } if(p->flags&VARADR) fprintf(f,"#"); if(p->flags&VAR) { printval(f,&p->val,MAXINT); if(p->flags®){ fprintf(f,"+%s",regnames[p->reg]); }else if(p->v->storage_class==AUTO||p->v->storage_class==REGISTER){ fprintf(f,"+%ld(FP)", zm2l(p->v->offset)); }else{ if(p->v->storage_class==STATIC){ fprintf(f,"+L%ld",zm2l(p->v->offset)); }else{ fprintf(f,"+_%s",p->v->identifier); } } if(*p->v->identifier) fprintf(f,"(%s)",p->v->identifier); else if(p->v->description) fprintf(f,"(%s)",p->v->description); else fprintf(f,"(%p)",(void *)p->v); if(p->v->reg) fprintf(f,":%s",regnames[abs(p->v->reg)]); } if((p->flags®)&&!(p->flags&VAR)) fprintf(f,"%s",regnames[p->reg]); if(p->flags&KONST){ fprintf(f,"#"); if(p->flags&DREFOBJ) printval(f,&p->val,p->dtyp&NU); else printval(f,&p->val,t&NU); } if(p->flags&SCRATCH) fprintf(f,"[S]"); if(p->flags&DREFOBJ) fprintf(f,")"); } void prl(FILE *o,struct struct_declaration *p) /* Gibt eine struct_declaration auf dem Bildschirm aus. */ { int i; static int recurse=2; int merk_recurse=recurse; --recurse; #ifdef HAVE_ECPP /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ #endif for(i=0;icount;i++){ fprintf(o," %d.:",i); if(recurse>=0){ if((*p->sl)[i].identifier)fprintf(o," ident: %s; ",(*p->sl)[i].identifier); prd(o,(*p->sl)[i].styp); } } recurse=merk_recurse; } void prd(FILE *o,struct Typ *p) /* Gibt einen Typ auf dem Bildschirm aus. */ { int f; if(!p) {fprintf(o,"empty type ");return;} f=p->flags; /* fprintf(o,"(Sizeof=%ld,flags=%d)",zl2l(szof(p)),f);*/ /* if(type_uncomplete(p)) {fprintf(o,"incomplete ");}*/ if(f&CONST) {fprintf(o,"const ");f&=~CONST;} if(f&STRINGCONST) {fprintf(o,"string-const ");f&=~STRINGCONST;} if(f&VOLATILE) {fprintf(o,"volatile ");f&=~VOLATILE;} if(f&UNSIGNED) {fprintf(o,"unsigned ");f&=~UNSIGNED;} if(p->attr) fprintf(o,"attr(%s) ",p->attr); if(p->reg) fprintf(o,"reg(%s) ",regnames[p->reg]); if(ISFUNC(f)){ fprintf(o,"%s with parameters (",typname[f&NQ]); prl(o,p->exact); fprintf(o,") returning ");prd(o,p->next);return; } if(ISSTRUCT(f)||ISUNION(f)){ fprintf(o,"%s with components {",typname[f&NQ]); prl(o,p->exact); fprintf(o,"} "); return; } if(ISPOINTER(f)) {fprintf(o,"%s to ",typname[f&NQ]);prd(o,p->next);return;} if(ISARRAY(f)) {fprintf(o,"%s [size %ld] of ",typname[f&NQ],zm2l(p->size));prd(o,p->next);return;} if(ISVECTOR(f)) {fprintf(o,"vector [size %ld] of %s",zm2l(p->size),typname[VECTYPE(f)&NQ]);return;} fprintf(o,"%s",typname[f&NQ]); } void print_var(FILE *o,struct Var *p) /* Gibt eine Variable aus. */ { if(p->identifier&&*p->identifier){ fprintf(o, "ident: %s: ", p->identifier); } prd(o, p->vtyp); } /* returns the first base Type in an compound type */ int get_first_base_type(struct Typ *t) { if (!t) return 0; if (ISARRAY(t->flags)) { return get_first_base_type(t->next); } else if ((ISSTRUCT(t->flags)) || (ISUNION(t->flags))) { return get_first_base_type((*t->exact->sl)[0].styp); } else return t->flags; } #ifndef HAVE_EXT_TYPES void insert_const(union atyps *p,int t) /* Traegt Konstante in entprechendes Feld ein. */ { if(!p) ierror(0); t&=NU; if(t==CHAR) {p->vchar=vchar;return;} if(t==SHORT) {p->vshort=vshort;return;} if(t==INT) {p->vint=vint;return;} if(t==LONG) {p->vlong=vlong;return;} if(t==LLONG) {p->vllong=vllong;return;} if(t==MAXINT) {p->vmax=vmax;return;} if(t==(UNSIGNED|CHAR)) {p->vuchar=vuchar;return;} if(t==(UNSIGNED|SHORT)) {p->vushort=vushort;return;} if(t==(UNSIGNED|INT)) {p->vuint=vuint;return;} if(t==(UNSIGNED|LONG)) {p->vulong=vulong;return;} if(t==(UNSIGNED|LLONG)) {p->vullong=vullong;return;} if(t==(UNSIGNED|MAXINT)) {p->vumax=vumax;return;} if(t==FLOAT) {p->vfloat=vfloat;return;} if(t==DOUBLE) {p->vdouble=vdouble;return;} if(t==LDOUBLE) {p->vldouble=vldouble;return;} if(t==POINTER) {p->vulong=vulong;return;} } void eval_const(union atyps *p,int t) /* Weist bestimmten globalen Variablen Wert einer CEXPR zu. */ { int f=t&NQ; if(!p) ierror(0); if(f==MAXINT||(f>=CHAR&&f<=LLONG)){ if(!(t&UNSIGNED)){ if(f==CHAR) vmax=zc2zm(p->vchar); else if(f==SHORT)vmax=zs2zm(p->vshort); else if(f==INT) vmax=zi2zm(p->vint); else if(f==LONG) vmax=zl2zm(p->vlong); else if(f==LLONG) vmax=zll2zm(p->vllong); else if(f==MAXINT) vmax=p->vmax; else ierror(0); vumax=zm2zum(vmax); vldouble=zm2zld(vmax); }else{ if(f==CHAR) vumax=zuc2zum(p->vuchar); else if(f==SHORT)vumax=zus2zum(p->vushort); else if(f==INT) vumax=zui2zum(p->vuint); else if(f==LONG) vumax=zul2zum(p->vulong); else if(f==LLONG) vumax=zull2zum(p->vullong); else if(f==MAXINT) vumax=p->vumax; else ierror(0); vmax=zum2zm(vumax); vldouble=zum2zld(vumax); } }else{ if(ISPOINTER(f)){ vumax=zul2zum(p->vulong); vmax=zum2zm(vumax);vldouble=zum2zld(vumax); }else{ if(f==FLOAT) vldouble=zf2zld(p->vfloat); else if(f==DOUBLE) vldouble=zd2zld(p->vdouble); else vldouble=p->vldouble; vmax=zld2zm(vldouble); vumax=zld2zum(vldouble); } } vfloat=zld2zf(vldouble); vdouble=zld2zd(vldouble); vuchar=zum2zuc(vumax); vushort=zum2zus(vumax); vuint=zum2zui(vumax); vulong=zum2zul(vumax); vullong=zum2zull(vumax); vchar=zm2zc(vmax); vshort=zm2zs(vmax); vint=zm2zi(vmax); vlong=zm2zl(vmax); vllong=zm2zll(vmax); } #endif struct function_info *new_fi(void) /* Belegt neue function_info-Struktur und initialisiert sie. */ { struct function_info *new; new=mymalloc(sizeof(*new)); new->first_ic=new->last_ic=new->opt_ic=0; new->vars=0; new->statics=0; new->inline_asm=0; new->flags=0; new->call_cnt=new->use_cnt=new->change_cnt=0; new->call_list=new->use_list=new->change_list=0; memset(new->regs_modified,0,sizeof(new->regs_modified)); #if HAVE_OSEK /* removed */ /* removed */ /* removed */ /* removed */ #endif new->stack1=ul2zum(0UL); new->stack2=ul2zum(0UL); return new; } void free_fi(struct function_info *p) /* Gibt ein function_info mit Inhalt frei. */ { if(p->first_ic) free_IC(p->first_ic); if(p->opt_ic) free_IC(p->opt_ic); if(p->vars) free_var(p->vars); /* do not free statics */ free(p->call_list); free(p->use_list); free(p->change_list); free(p->inline_asm); free(p); } void print_fi(FILE *f,struct function_info *p) /* Gibt function_info aus. */ { int i; fprintf(f,"function_info:\n"); if(p->first_ic){ struct IC *ic=p->first_ic; fprintf(f," inline_code:\n"); pric2(f,ic); while(ic!=p->last_ic){ ic=ic->next; pric2(f,ic); } } if(p->inline_asm) fprintf(f," inline_asm:\n%s\n",p->inline_asm); if(p->flags&ALL_CALLS) fprintf(f," all calls have been evaluated\n"); if(p->flags&ALL_USES) fprintf(f," all uses have been evaluated\n"); if(p->flags&ALL_MODS) fprintf(f," all changes have been evaluated\n"); if(p->flags&ALL_REGS){ fprintf(f," all reg-changes have been evaluated\n"); for(i=1;i<=MAXR;i++) if(BTST(p->regs_modified,i)) fprintf(f," %s\n",regnames[i]); } fprintf(f," call_list:\n");print_varlist(f,p->call_list,p->call_cnt); fprintf(f," use_list:\n");print_varlist(f,p->use_list,p->use_cnt); fprintf(f," change_list:\n");print_varlist(f,p->change_list,p->change_cnt); if(p->flags&ALL_STACK){ fprintf(f,"stack1: ");printzum(f,p->stack1);fprintf(f,"\n"); fprintf(f,"stack2: ");printzum(f,p->stack2);fprintf(f,"\n"); } if(p->flags&NEVER_RETURNS) fprintf(f," never returns\n"); if(p->flags&ALWAYS_RETURNS) fprintf(f," always returns\n"); if(p->flags&NOSIDEFX) fprintf(f," no side effects\n"); } void print_varlist(FILE *f,struct varlist *p,int n) { int i; char *s; for(i=0;iidentifier; else s=""; fprintf(f," %s(%p), flags=%d\n",s,(void*)p[i].v,p[i].flags); } } int is_const(struct Typ *t) /* tested, ob ein Typ konstant (und damit evtl. in der Code-Section) ist */ { if(!(t->flags&(CONST|STRINGCONST))){ do{ if(t->flags&(CONST|STRINGCONST)) return(1); if((t->flags&NQ)!=ARRAY) return 0; t=t->next; }while(1); }else return 1; } /* is object volatile? */ int is_volatile_obj(struct obj *o) { if(o->flags&DREFOBJ){ if(o->dtyp&VOLATILE) return 1; if((o->flags&VAR)&&ISPOINTER(o->v->vtyp->flags)&&(o->v->vtyp->next->flags&VOLATILE)) return 1; } if(o->flags&VAR) return o->v->vtyp->flags&VOLATILE; else return 0; } /* is IC volatile? */ int is_volatile_ic(struct IC *p) { if(p->q1.flags){ if(is_volatile_obj(&p->q1)||(q1typ(p)&VOLATILE)) return 1; } if(p->q2.flags){ if(is_volatile_obj(&p->q2)||(q2typ(p)&VOLATILE)) return 1; } if(p->z.flags){ if(is_volatile_obj(&p->z)||(ztyp(p)&VOLATILE)) return 1; } return 0; } /* removes last asm-line from emit-buffer */ void remove_asm(void) { emit_l--; if(emit_l<0) emit_l=EMIT_BUF_DEPTH-1; } /* flush the asm-output buffer */ void emit_flush(FILE *f) { if(!f||no_emit) return; while(emit_f!=emit_l){ fputs(emit_buffer[emit_f],f); emit_f++; if(emit_f>=EMIT_BUF_DEPTH) emit_f=0; } emit_l=emit_f=0; emit_p=emit_buffer[0]; } /* emit inline-asm, depending on no_inline_peephole, feed it through asm_peephole() or flush the buffer and print it directly to the file */ void emit_inline_asm(FILE *f,char *p) { if(!f||no_emit) return; if(no_inline_peephole){ emit_flush(f); fprintf(f,"%s\n",p); }else{ while(*p){ emit(f,"%c",*p++); } emit(f,"\n"); } } /* print output; this is only to be used for assembly output! */ void emit(FILE *f,const char *fmt,...) { static char tmp[EMIT_BUF_LEN]; char *p; va_list vl; if(!f||no_emit) return; va_start(vl,fmt); vsprintf(tmp,fmt,vl); p=tmp; while(*p){ *emit_p++=*p++; if(p[-1]=='\n'){ *emit_p=0; #if HAVE_TARGET_PEEPHOLE while(emit_peephole()); #endif emit_l++; if(emit_l>=EMIT_BUF_DEPTH) emit_l=0; emit_p=emit_buffer[emit_l]; if(emit_l==emit_f){ /* FIXME: error check */ fputs(emit_buffer[emit_f],f); emit_f++; if(emit_f>=EMIT_BUF_DEPTH) emit_f=0; } } } *emit_p=0; } void emit_char(FILE *f,int c) { static char tmp[2]; tmp[0]=c; emit(f,tmp); } /* detect whether the following code resembles a switch-case-statement */ /* will return the longest sequence which has at least min_density */ struct case_table *calc_case_table(struct IC *p,double min_density) { static struct case_table ct; struct obj *o,*ccr; static union atyps *vals; union atyps min,max; zumax diff; static int *labels,cur_size; double cur_density; int t,j,num; if(p->code!=COMPARE||!(p->q2.flags&KONST)) return 0; o=&p->q1;t=p->typf; if(!ISINT(t)||(t&VOLATILE)) return 0; num=0; ct.num=0; if(t&UNSIGNED){ max.vumax=t_min(UNSIGNED|MAXINT); min.vumax=t_max(UNSIGNED|MAXINT); }else{ max.vmax=t_min(MAXINT); min.vmax=t_max(MAXINT); } while(p&&p->code==COMPARE&&(p->q2.flags&KONST)&&p->typf==t&&!compare_objs(o,&p->q1,t)){ zumax zum;zmax zm; if(multiple_ccs) ccr=&p->z; if(num>=cur_size){ cur_size+=64; labels=myrealloc(labels,cur_size*sizeof(*labels)); vals=myrealloc(vals,cur_size*sizeof(*vals)); } for(j=0;jq2.val,t)){ return 0; /* FIXME? Could simply ignore? */ } } vals[num]=p->q2.val; p=p->next; while(p&&(p->code==NOP||p->code==ALLOCREG||p->code==FREEREG)) p=p->next; if(p->code!=BEQ||(multiple_ccs&&compare_objs(ccr,&p->q1,0))) break; labels[num]=p->typf; p=p->next; while(p&&(p->code==NOP||p->code==ALLOCREG||p->code==FREEREG)) p=p->next; eval_const(&vals[num],t); num++; if(t&UNSIGNED){ if(zumleq(vumax,min.vumax)) insert_const(&min,UNSIGNED|MAXINT); if(zumleq(max.vumax,vumax)) insert_const(&max,UNSIGNED|MAXINT); cur_density=num/(1+zld2d(zum2zld(zumsub(max.vumax,min.vumax)))); if(cur_density>=min_density){ ct.num=num; ct.next_ic=p; ct.min=min; ct.max=max; ct.diff=zumsub(max.vumax,min.vumax); ct.density=cur_density; } }else{ if(zmleq(vmax,min.vmax)) insert_const(&min,MAXINT); if(zmleq(max.vmax,vmax)) insert_const(&max,MAXINT); cur_density=num/zld2d(zum2zld((1+zumsub(zm2zum(max.vmax),zm2zum(min.vmax))))); if(cur_density>=min_density){ ct.num=num; ct.next_ic=p; ct.min=min; ct.max=max; ct.diff=zumsub(zm2zum(max.vmax),zm2zum(min.vmax)); ct.density=cur_density; } } } ct.vals=vals; ct.labels=labels; ct.typf=t; return &ct; } /* emit a list of jump-table entries */ void emit_jump_table(FILE *f,struct case_table *ct,char *da,char *labprefix,int defl) { unsigned long l,e; int i; zmax zm;zumax zum; if(ct->typf&UNSIGNED){ zum=ct->min.vumax; zm=zum2zm(zum); }else{ zm=ct->min.vmax; zum=zm2zum(zm); } e=zum2ul(ct->diff); for(l=0;l<=e;l++){ emit(f,"%s",da); for(i=0;inum;i++){ eval_const(&ct->vals[i],ct->typf); if(zmeqto(vmax,zm)&&zumeqto(vumax,zum)){ emit(f,"%s%d\n",labprefix,ct->labels[i]); break; } } if(i>=ct->num) emit(f,"%s%d\n",labprefix,defl); zm=zmadd(zm,l2zm(1L)); zum=zumadd(zum,ul2zum(1UL)); } } /* display warnings if specified stack-size cannot be guaranteed */ void static_stack_check(struct Var *v) { /*FIXME*/ } #ifdef HAVE_REGPARMS /* return the offset of the first variable-argument-macro to the beginning of the argument-area (i.e. the space occupied by normal arguments on the stack */ zmax va_offset(struct Var *v) { int i; zmax offset=l2zm(0L); struct reg_handle rh=empty_reg_handle; for(i=0;ivtyp->exact->count;i++){ #if 0 if((*v->vtyp->exact->sl)[i].reg!=0) continue; #endif if(((*v->vtyp->exact->sl)[i].styp->flags&NQ)==VOID) ierror(0); if(reg_parm(&rh,(*v->vtyp->exact->sl)[i].styp,0,v->vtyp)!=0) continue; offset=zmadd(offset,szof((*v->vtyp->exact->sl)[i].styp)); offset=zmmult(zmdiv(zmadd(offset,zmsub(stackalign,l2zm(1L))),stackalign),stackalign); } return offset; } #endif /* We provide an own qsort to get reproducable results. */ void vqsort (void *base,size_t nmemb,size_t size,int (*compar)(const void *,const void *)) { char *base2=(char *)base; char tmp; size_t i,a,b,c; while(nmemb>1) { a=0; b=nmemb-1; c=(a+b)/2; /* Middle element */ for(;;) { while((*compar)(&base2[size*c],&base2[size*a])>0) a++; /* Look for one >= middle */ while((*compar)(&base2[size*c],&base2[size*b])<0) b--; /* Look for one <= middle */ if(a>=b) break; /* We found no pair */ for(i=0;icall_cnt){ for(i=0;icall_cnt;i++){ if(p->call_list[i].v->fi&&(p->call_list[i].v->fi->flags&ALL_REGS)){ bvunite(regs_modified,p->call_list[i].v->fi->regs_modified,RSIZE); #if HAVE_OSEK /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ #endif }else{ int r; for(r=1;r<=MAXR;r++) if(regscratch[r]) BSET(regs_modified,r); err_ic=p; if(!p->call_list[i].v->fi) p->call_list[i].v->fi=new_fi(); if(!(p->call_list[i].v->fi->flags&WARNED_REGS)){ error(318,p->call_list[i].v->identifier); p->call_list[i].v->fi->flags|=WARNED_REGS; } return 0; } } return 1; } err_ic=p;if(showwarnings) error(320); return 0; } #ifndef HAVE_TARGET_BFLAYOUT int bflayout(int bfoffset,int bfsize,int t) { if(BIGENDIAN) return (int)zm2l(zmmult(sizetab[t&NQ],char_bit))-bfoffset-bfsize; else return bfoffset; } #endif #ifdef HAVE_MISRA /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ /* removed */ #endif