1687 lines · 41.1 KB · C
RawDownload
#include "supp.h"#include "opt.h" static char FILE_[]=__FILE__; #ifndef HAVE_EXT_TYPESchar *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 DEBUGint 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;i<new->arg_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_FALIGNzmax 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;i<t->exact->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_SZOFzmax 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);j<t->exact->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;j<t->exact->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(i<sd->count&&strcmp((*sd->sl)[i].identifier,identifier)){    if((*sd->sl)[i].bfoffset>=0){      if(i+1<sd->count&&(*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 */

Lines 1–500 of 1687.