blob: fd100324ffdf919fbfee9f60d336ddfe2599da0d [file] [log] [blame]
PulkoMandy17fc7592022-07-28 18:27:54 +02001/* $VER: vbcc (supp.c) $Revision: 1.49 $ */
2
3#include "supp.h"
4#include "opt.h"
5
6static char FILE_[]=__FILE__;
7
8#ifndef HAVE_EXT_TYPES
9char *typname[]={"strange","char","short","int","long","long long",
10 "float","double","long double","void",
11 "pointer","array","struct","union","enum","function",
12 "bool","vector"};
13#endif
14
15char *storage_class_name[]={"strange","auto","register","static","extern","typedef"};
16
17char *ename[]={"strange","sequence","move","set+","set-","set*","set/","set%",
18 "set&","set^","set|","set<<","set>>","?:","lor","land","or",
19 "eor","and","eq","neq","lt","le","gt","ge","lsl",
20 "lsr","add","sub","mul","div","mod","negate",
21 "not","preinc","postinc","predec","postdec","neg",
22 "dref-pointer","address-of","cast","call","index",
23 "dref-struct-pointer","dref-struct","identifier","constant",
24 "string","member",
25 "convert","convert-short","convert-int","convert-long",
26 "convert-float","convert-double","convert-void","convert-pointer",
27 "convert-uchar","convert-ushort","convert-uint","convert-ulong",
28 "address-of-array","first-element-of-array","pmult",
29 "allocreg","freereg","pconstant","test","label","beq","bne",
30 "blt","bge","ble","bgt","bra","compare","push","pop",
31 "address-of-struct","add-int-to-pointer","sub-int-from-pointer",
32 "sub-pointer-from-pointer","push-reg","pop-reg","pop-args",
33 "save-regs","restore-regs","identifier-label","dc","align",
34 "colon","get-return","set-return","move-from-reg","move-to-reg",
35 "nop","bitfield"};
36
37char *empty="";
38zchar vchar; zuchar vuchar;
39zshort vshort; zushort vushort;
40zint vint; zuint vuint;
41zlong vlong; zulong vulong;
42zllong vllong; zullong vullong;
43zmax vmax; zumax vumax;
44zfloat vfloat; zdouble vdouble;
45zldouble vldouble;
46
47union atyps gval;
48
49#ifndef DEBUG
50int DEBUG;
51#endif
52
53int label;
54
55int regs[MAXR+1],regused[MAXR+1],simple_scratch[MAXR+1];
56Var *regsv[MAXR+1];
57int goto_used;
58int ic_count;
59zmax max_offset;
60int function_calls,vlas;
61int coloring;
62int dmalloc;
63int disable;
64int multiple_ccs;
65int lastlabel,return_label;
66int only_inline;
67IC *err_ic;
68long maxoptpasses=30;
69long optflags;
70int optsize,optspeed,unroll_all,stack_check;
71int cross_module,final,no_emit;
72int debug_info;
73long inline_size=100;
74long inline_depth=1;
75long unroll_size=200;
76long clist_copy_stack=6;
77long clist_copy_static=6;
78long clist_copy_pointer=20;
79long inline_memcpy_sz=INLINEMEMCPY;
80int fp_assoc,noaliasopt,noitra;
81char *filename;
82IC *first_ic,*last_ic;
83int float_used;
84bvtype regs_modified[RSIZE/sizeof(bvtype)];
85/* Das haette ich gern woanders */
86Var *vl0,*vl1,*vl2,*vl3;
87int align_arguments=1;
88zmax stackalign;
89int misracheck,misraversion,misracomma,misratok;
90int pack_align;
91int short_push;
92int default_unsigned;
93Var *add_attr_haddecl;
94
95char *emit_buffer[EMIT_BUF_DEPTH];
96char *emit_p;
97int emit_f,emit_l;
98int no_inline_peephole;
99
100static int get_scalar_byte(int f,union atyps *v,zmax n, zuchar *out)
101/* Yields byte n of a constant */
102{
103 if(!zmleq(l2zm(0L),n)) ierror(0);
104 f&=NQ;
105 if(f>=CHAR&&f<=LLONG){
106 int j;
107 eval_const(v,f);
108 if(LITTLEENDIAN)
109 j=zm2l(n);
110 else
111 j=(int)sizetab[f]-(int)zm2l(n)-1;
112 while(j){
113 vumax=zumrshift(vumax,char_bit);
114 j--;
115 }
116 *out=zum2zuc(vumax);
117 return 1;
118 }else
119 return 0;
120}
121
122zumax get_clist_int(type *t, const_list *cl, zmax n, int sz,int *state)
123/* yields an integer of size sz from offset n */
124{
125 zuchar zuc;
126 zumax val = ZU0;
127
128 if(LITTLEENDIAN)
129 n=zmadd(n,l2zm((long)(sz-1)));
130
131 while(sz){
132 val=zumlshift(val,char_bit);
133 if(!get_clist_byte(t,cl,n,&zuc)) {*state=0;return ZU0;}
134 val=zumadd(val,zuc2zum(zuc));
135 sz--;
136 n=LITTLEENDIAN?zmsub(n,Z1):zmadd(n,Z1);
137 }
138 *state=1;
139 return val;
140}
141
142int get_clist_byte(type *t,const_list *cl, zmax n, zuchar *out)
143/* Yields byte n from a const list */
144{
145 if(!cl){
146 *out=zum2zuc(ul2zum(0UL));
147 return 1;
148 }
149
150 if(ISARRAY(t->flags)){
151 zmax i,j,x;
152 x=szof(t->next);
153 i=zmdiv(n,x);
154 while(1){
155 if(!cl) break;
156 if(zmleq(i,cl->idx)) break;
157 cl=cl->next;
158 }
159 if(!cl||!zmeqto(cl->idx,i)){
160 *out=zum2zuc(ul2zum(0UL));
161 return 1;
162 }
163 return get_clist_byte(t->next,cl->other,zmmod(n,x),out);
164 }
165 if(ISUNION(t->flags)){
166 int i=zm2l(cl->idx);
167 if(cl->tree) return 0;
168 return get_clist_byte((*t->exact->sl)[i].styp,cl->other,n,out);
169 }
170 if(ISSTRUCT(t->flags)){
171 zmax al;int fl;type *st;
172 int i,bfo,bfs;zmax sz;zumax bfval=ul2zum(0UL);
173
174 sz=l2zm(0L);
175 if(cl&&cl->tree){
176 /* initialized by another */
177 return 0;
178 }else{
179 for(i=0;i<t->exact->count&&cl;i++){
180 if(!cl->other){ierror(0);}
181 st=(*t->exact->sl)[i].styp;
182 al=(*t->exact->sl)[i].align;
183 if(!(*t->exact->sl)[i].identifier) ierror(0);
184 bfo=(*t->exact->sl)[i].bfoffset;
185 if(!zmeqto(zmmod(sz,al),l2zm(0L))){
186 sz=zmadd(sz,zmsub(al,zmmod(sz,al)));
187 if(!zmleq(sz,n)){
188 *out=zum2zuc(ul2zum(0L));
189 return 1;
190 }
191 }
192 if(bfo>=0){
193 /* bitfield */
194
195 if((*t->exact->sl)[i].identifier[0]){
196 bfs=(*t->exact->sl)[i].bfsize;
197 if(zmeqto(l2zm((long)i),cl->idx)){
198 eval_const(&cl->other->val,st->flags);
199 cl=cl->next;
200 }else{
201 vumax=ul2zum(0UL);
202 }
203 vumax=zumand(vumax,zumsub(zumlshift(ul2zum(1UL),ul2zum((unsigned long)bfs)),ul2zum(1UL)));
204 bfval=zumor(bfval,zumlshift(vumax,ul2zum((unsigned long)bflayout(bfo,bfs,st->flags))));
205 }
206 if(i+1>=t->exact->count||(*t->exact->sl)[i+1].bfoffset<=0||!cl){
207 /* last bitfield in integer */
208 gval.vumax=bfval;
209 eval_const(&gval,UNSIGNED|MAXINT);
210 insert_const(&gval,st->flags&NU);
211 bfval=ul2zum(0L);
212 sz=zmadd(sz,szof(st));
213 if(!zmleq(sz,n))
214 return get_scalar_byte(st->flags,&gval,zmsub(n,zmsub(sz,szof(st))),out);
215 }
216 }else{
217 sz=zmadd(sz,szof(st));
218 if(!zmleq(sz,n)){
219 if(zmeqto(l2zm((long)i),cl->idx)){
220 return get_clist_byte(st,cl->other,zmsub(n,zmsub(sz,szof(st))),out);
221 }else{
222 *out=zum2zuc(ul2zum(0UL));
223 return 1;
224 }
225 }
226 if(zmeqto(l2zm((long)i),cl->idx))
227 cl=cl->next;
228 }
229 }
230 }
231 *out=zum2zuc(ul2zum(0UL));
232 return 1;
233 }
234
235 if(zmeqto(cl->idx,l2zm(-1L)))
236 return 0;
237 else{
238 if(cl->tree)
239 return 0;
240 else
241 return get_scalar_byte(t->flags,&cl->val,n,out);
242
243 }
244 ierror(0);
245}
246
247type *new_typ(void)
248/* Erzeigt neuen (leeren) Typ. */
249{
250 type *new=mymalloc(TYPS);
251 new->flags=0;
252 new->next=0;
253 new->exact=0;
254 new->attr=0;
255 new->dsize=0;
256 new->reg=0;
257#ifdef HAVE_ECPP
258/* removed */
259#endif
260 return new;
261}
262
263type *clone_typ(type *old)
264/* Erzeugt Kopie eines Typs und liefert Zeiger auf Kopie. */
265{
266 type *new;
267 if(!old) return 0;
268 new=new_typ();
269 *new=*old;
270 if(old->attr){
271 new->attr=mymalloc(strlen(old->attr)+1);
272 strcpy(new->attr,old->attr);
273 }
274 if(new->next) new->next=clone_typ(new->next);
275 return new;
276}
277Var *new_var(void)
278{
279 Var *new=mymalloc(sizeof(*new));
280 new->clist=0;
281 new->vtyp=0;
282 new->storage_class=0;
283 new->reg=0;
284 new->vattr=0;
285 new->next=0;
286 new->flags=0;
287 new->fi=0;
288 new->nesting=0;
289 new->filename=0;
290 new->line=0;
291 new->dfilename=0;
292 new->dline=0;
293 new->description=0;
294 new->tunit=0;
295 new->offset=l2zm(0L);
296 new->identifier=0;
297#ifdef HAVE_TARGET_ATTRIBUTES
298 new->tattr=0;
299#endif
300#ifdef ALEX_REG
301 new->iRegCopyNr = -1;
302 new->iRegCopyNrHc12V = -1;
303#endif
304 return new;
305}
306
307IC *new_IC(void)
308{
309 IC *p=mymalloc(ICS);
310 p->change_cnt=0;
311 p->use_cnt=0;
312 p->call_cnt=0;
313 p->arg_cnt=0;
314 p->use_list=0;
315 p->change_list=0;
316 p->call_list=0;
317 p->arg_list=0;
318 p->line=0;
319 p->file=0;
320 p->flags=0;
321 p->q1.flags=p->q2.flags=p->z.flags=0;
322 p->q1.am=p->q2.am=p->z.am=0;
323 p->q1.val.vmax=p->q2.val.vmax=p->z.val.vmax=l2zm(0L);
324 p->savedsp=0;
325 p->typf=p->typf2=0;
326#ifdef ALEX_REG
327 p->iZWebIndex = -1;
328 p->iQ1WebIndex = -1;
329 p->iQ2WebIndex = -1;
330 p->pFlow = NULL;
331#endif /* GC_RALLOC */
332
333 return p;
334}
335/* (partially) clones an IC list */
336IC *clone_ic(IC *p)
337{
338 IC *new,*first,*last;
339 first=last=new=0;
340 while(p){
341 new=mymalloc(sizeof(*new));
342 *new=*p;
343 p->copy=new;
344
345 if(p->q1.am||p->q2.am||p->z.am) ierror(0);
346
347 if(new->code==CALL){
348 int i;
349 new->arg_list=mymalloc(sizeof(*new->arg_list)*new->arg_cnt);
350 for(i=0;i<new->arg_cnt;i++){
351 if(!p->arg_list[i])
352 ierror(0);
353 if(!p->arg_list[i]->copy)
354 ierror(0);
355 new->arg_list[i]=p->arg_list[i]->copy;
356 }
357 }
358 new->prev=last;
359 new->next=0;
360 if(!first) first=new;
361 if(last) last->next=new;
362 last=new;
363 p=p->next;
364 }
365 return first;
366}
367void free_IC(IC *p)
368/* Gibt IC-Liste inkl. Typen frei. */
369{
370 IC *merk;
371 if(DEBUG&1) printf("free_IC()\n");
372 while(p){
373 /*if(p->q1.am&&!p->q1.flags) ierror(0);
374 if(p->q2.am&&!p->q2.flags) ierror(0);
375 if(p->z.am&&!p->z.flags) ierror(0);*/
376
377 if(p->q1.am&&p->q1.am==p->q2.am)
378 ierror(0);
379
380 if(p->q1.am) free(p->q1.am);
381 if(p->q2.am) free(p->q2.am);
382 if(p->z.am) free(p->z.am);
383 if(p->code==CALL) free(p->arg_list);
384 merk=p->next;
385 free(p);
386 p=merk;
387 }
388}
389void move_IC(IC *after,IC *p)
390{
391 if(p->prev)
392 p->prev->next=p->next;
393 else
394 first_ic=p->next;
395 if(p->next)
396 p->next->prev=p->prev;
397 else
398 last_ic=p->prev;
399 insert_IC(after,p);
400}
401void remove_IC(IC *p)
402/* Entfernt IC p aus Liste. */
403{
404 if(p->prev) p->prev->next=p->next; else first_ic=p->next;
405 if(p->next) p->next->prev=p->prev; else last_ic=p->prev;
406 if(p->q1.am) free(p->q1.am);
407 if(p->q2.am) free(p->q2.am);
408 if(p->z.am) free(p->z.am);
409 free(p);
410}
411void freetyp(type *p)
412/* Gibt eine Typ-Liste frei, aber keine struct_declaration oder so. */
413{
414 int f;type *merk;
415 if(DEBUG&8){printf("freetyp: ");prd(stdout,p);printf("\n");}
416 while(p){
417 merk=p->next;
418 f=p->flags&NQ;
419 if(merk&&!ISARRAY(f)&&!ISPOINTER(f)&&!ISFUNC(f)&&!ISVECTOR(f))
420 ierror(0);
421 free(p->attr);
422 free(p);
423 p=merk;
424 }
425}
426
427#ifndef HAVE_TGT_FALIGN
428zmax falign(type *t)
429/* Liefert Alignment eines Typs. Funktioniert im Gegensatz zum */
430/* align[]-Array auch mit zusammengesetzten Typen. */
431{
432 int i,f; zmax al,alt;
433 f=t->flags&NQ;
434 if(ISVECTOR(f)) return szof(t);
435 al=align[f];
436 if(ISSCALAR(f)) return al;
437 if(ISARRAY(f)){
438 do{
439 t=t->next;
440 f=t->flags&NQ;
441 }while(ISARRAY(f)||ISVECTOR(f));
442 alt=falign(t);
443 if(zmleq(al,alt)) return alt; else return al;
444 }
445 if(ISUNION(f)||ISSTRUCT(f)){
446 if(!t->exact) ierror(0);
447 for(i=0;i<t->exact->count;i++){
448 alt=(*t->exact->sl)[i].align;
449 if(!zmleq(alt,al)) al=alt;
450 }
451 }
452 return al;
453}
454#endif
455
456/* check, whether t is a variable length array */
457int is_vlength(type *t)
458{
459 if(!ISARRAY(t->flags))
460 return 0;
461 if(t->dsize)
462 return 1;
463 else
464 return is_vlength(t->next);
465}
466
467/* calculate size of a variable length array */
468Var *vlength_szof(type *t)
469{
470 IC *new;type *nt;
471 if(!ISARRAY(t->flags))
472 ierror(0);
473 new=new_IC();
474 new->code=MULT;
475 new->typf=HAVE_INT_SIZET?(UNSIGNED|INT):(UNSIGNED|LONG);
476 if(t->dsize){
477 new->q1.flags=VAR;
478 new->q1.v=t->dsize;
479 new->q1.val.vmax=l2zm(0L);
480 }else{
481 new->q1.flags=KONST;
482#if HAVE_INT_SIZET
483 new->q1.val.vuint=zum2zui(zm2zum(t->size));
484#else
485 new->q1.val.vulong=zum2zul(zm2zum(t->size));
486#endif
487 }
488 new->z.flags=VAR;
489 nt=new_typ();
490 nt->flags=new->typf;
491 new->z.v=add_tmp_var(nt);
492 new->z.val.vmax=l2zm(0L);
493 if(is_vlength(t->next)){
494 new->q2.flags=VAR;
495 new->q2.v=vlength_szof(t->next);
496 new->q2.val.vmax=l2zm(0L);
497 }else{
498 new->q2.flags=KONST;
499#if HAVE_INT_SIZET
500 new->q2.val.vuint=zum2zui(zm2zum(szof(t->next)));
501#else
502 new->q2.val.vulong=zum2zul(zm2zum(szof(t->next)));
503#endif
504 }
505 add_IC(new);
506 return new->z.v;
507}
508
509/* return the type of a d-dim vector of base type x */
510int mkvec(int x,int d)
511{
512 int t=x&NQ,r;
513 if(d!=2&&d!=3&&d!=4&&d!=8&&d!=16) ierror(0);
514 switch(t){
515 case BOOL:
516 r=VECBOOL;break;
517 case CHAR:
518 r=VECCHAR;break;
519 case SHORT:
520 r=VECSHORT;break;
521 case INT:
522 r=VECINT;break;
523 case LONG:
524 r=VECLONG;break;
525 case FLOAT:
526 r=VECFLOAT;break;
527 default:
528 ierror(0);
529 }
530 return (r+d-1)|(x&~NQ);
531}
532
533/* return the base type of a vector */
534int VECTYPE(int x)
535{
536 int t=x&NQ,r=0;
537 if(t>=VECBOOL&&t<=VECBOOL+MAXVECDIM)
538 r=BOOL;
539 if(t>=VECCHAR&&t<=VECCHAR+MAXVECDIM)
540 r=CHAR;
541 if(t>=VECSHORT&&t<=VECSHORT+MAXVECDIM)
542 r=SHORT;
543 if(t>=VECINT&&t<=VECINT+MAXVECDIM)
544 r=INT;
545 if(t>=VECLONG&&t<=VECLONG+MAXVECDIM)
546 r=LONG;
547 if(t>=VECFLOAT&&t<=VECFLOAT+MAXVECDIM)
548 r=FLOAT;
549 if(!r) ierror(0);
550 return r|(x&~NQ);
551}
552
553
554#ifndef HAVE_TGT_SZOF
555zmax szof(type *t)
556/* Liefert die benoetigte Groesse eines Typs in Bytes. */
557{
558 int i=t->flags&NQ,j;zmax size,m;
559#ifdef HAVE_ECPP
560/* removed */
561#endif
562
563 if(ISSCALAR(i)) return sizetab[i];
564 if(ISARRAY(i)){
565 if(is_vlength(t))
566 return sizetab[POINTER_TYPE(t->next)];
567 size=zmmult((t->size),szof(t->next));
568 m=align[ARRAY];
569 return zmmult(zmdiv(zmadd(size,zmsub(m,l2zm(1L))),m),m); /* align */
570 }
571 if(ISVECTOR(i)){
572 zmax dim=VECDIM(i);
573 if(zmeqto(dim,l2zm(3L))) dim=l2zm(4L);
574 return zmmult(dim,sizetab[VECTYPE(i)&NQ]);
575 }
576 if(ISUNION(i)){
577 for(j=0,size=l2zm(0L);j<t->exact->count;j++){
578 m=szof((*t->exact->sl)[j].styp);
579 if(zmeqto(m,l2zm(0L))) return l2zm(0L);
580 if(!zmleq(m,size)) size=m;
581 }
582 m=falign(t);
583 return zmmult(zmdiv(zmadd(size,zmsub(m,l2zm(1L))),m),m); /* align */
584 }
585 if(ISSTRUCT(i)){
586 size=l2zm(0L);
587#ifdef HAVE_ECPP
588/* removed */
589/* removed */
590/* removed */
591/* removed */
592/* removed */
593/* removed */
594/* removed */
595#endif
596 for(j=0;j<t->exact->count;j++){
597 type *h=(*t->exact->sl)[j].styp;
598 if((*t->exact->sl)[j].bfoffset<=0){
599 int n;size_t al;
600 al=(*t->exact->sl)[j].align;
601#ifdef HAVE_ECPP
602/* removed */
603#endif
604 if(zmeqto(al,l2zm(0L))) {prd(stdout,h);ierror(0);}
605 m=szof(h);
606 /* find the largest type in a bitfield */
607 for(n=j+1;n<t->exact->count&&(*t->exact->sl)[n].bfoffset>0;n++){
608 size_t tmp=szof((*t->exact->sl)[n].styp);
609 if(zmleq(m,tmp))
610 m=tmp;
611 }
612 size=zmmult(zmdiv(zmadd(size,zmsub(al,l2zm(1L))),al),al);
613 /*if(zmeqto(m,l2zm(0L))) return l2zm(0L);*/
614 size=zmadd(size,m);
615 }
616 }
617 m=falign(t);
618 return zmmult(zmdiv(zmadd(size,zmsub(m,l2zm(1L))),m),m); /* align */
619 }
620 return sizetab[i];
621}
622zmax struct_offset(struct_declaration *sd,const char *identifier)
623{
624 int i=0,intbitfield=-1;zmax offset=l2zm(0),al;
625 while(i<sd->count&&strcmp((*sd->sl)[i].identifier,identifier)){
626 if((*sd->sl)[i].bfoffset>=0){
627 if(i+1<sd->count&&(*sd->sl)[i+1].bfoffset>0){
628 i++;
629 continue;
630 }
631 }
632 al=(*sd->sl)[i].align;
633 offset=zmmult(zmdiv(zmadd(offset,zmsub(al,l2zm(1L))),al),al);
634 offset=zmadd(offset,szof((*sd->sl)[i].styp));
635 i++;
636 }
637 if(i>=sd->count) {error(23,identifier);return l2zm(0L);}
638 al=(*sd->sl)[i].align;
639 offset=zmmult(zmdiv(zmadd(offset,zmsub(al,l2zm(1L))),al),al);
640 return offset;
641}
642#ifdef HAVE_ECPP
643/* removed */
644/* removed */
645/* removed */
646/* removed */
647/* removed */
648/* removed */
649/* removed */
650/* removed */
651/* removed */
652/* removed */
653/* removed */
654/* removed */
655/* removed */
656/* removed */
657/* removed */
658/* removed */
659/* removed */
660/* removed */
661/* removed */
662/* removed */
663/* removed */
664/* removed */
665/* removed */
666/* removed */
667/* removed */
668/* removed */
669/* removed */
670/* removed */
671/* removed */
672/* removed */
673/* removed */
674/* removed */
675#endif
676#endif
677
678#ifndef HAVE_TGT_PRINTVAL
679void printval(FILE *f,union atyps *p,int t)
680/* Gibt atyps aus. */
681{
682 t&=NU;
683 if(t==CHAR){fprintf(f,"C");vmax=zc2zm(p->vchar);printzm(f,vmax);}
684 if(t==(UNSIGNED|CHAR)){fprintf(f,"UC");vumax=zuc2zum(p->vuchar);printzum(f,vumax);}
685 if(t==SHORT){fprintf(f,"S");vmax=zs2zm(p->vshort);printzm(f,vmax);}
686 if(t==(UNSIGNED|SHORT)){fprintf(f,"US");vumax=zus2zum(p->vushort);printzum(f,vumax);}
687 if(t==FLOAT){fprintf(f,"F");vldouble=zf2zld(p->vfloat);printzld(f,vldouble);}
688 if(t==DOUBLE){fprintf(f,"D");vldouble=zd2zld(p->vdouble);printzld(f,vldouble);}
689 if(t==LDOUBLE){fprintf(f,"LD");printzld(f,p->vldouble);}
690 if(t==INT){fprintf(f,"I");vmax=zi2zm(p->vint);printzm(f,vmax);}
691 if(t==(UNSIGNED|INT)){fprintf(f,"UI");vumax=zui2zum(p->vuint);printzum(f,vumax);}
692 if(t==LONG){fprintf(f,"L");vmax=zl2zm(p->vlong);printzm(f,vmax);}
693 if(t==(UNSIGNED|LONG)){fprintf(f,"UL");vumax=zul2zum(p->vulong);printzum(f,vumax);}
694 if(t==LLONG){fprintf(f,"LL");vmax=zll2zm(p->vllong);printzm(f,vmax);}
695 if(t==(UNSIGNED|LLONG)){fprintf(f,"ULL");vumax=zull2zum(p->vullong);printzum(f,vumax);}
696 if(t==MAXINT){fprintf(f,"M");printzm(f,p->vmax);}
697 if(t==(UNSIGNED|MAXINT)){fprintf(f,"UM");printzum(f,p->vumax);}
698 /*FIXME*/
699 if(t==POINTER){fprintf(f,"P");vumax=zul2zum(p->vulong);printzum(f,vumax);}
700}
701void emitval(FILE *f,union atyps *p,int t)
702/* Gibt atyps aus. */
703{
704 t&=NU;
705 if(t==CHAR){vmax=zc2zm(p->vchar);emitzm(f,vmax);}
706 if(t==(UNSIGNED|CHAR)){vumax=zuc2zum(p->vuchar);emitzum(f,vumax);}
707 if(t==SHORT){vmax=zs2zm(p->vshort);emitzm(f,vmax);}
708 if(t==(UNSIGNED|SHORT)){vumax=zus2zum(p->vushort);emitzum(f,vumax);}
709 if(t==FLOAT){vldouble=zf2zld(p->vfloat);emitzld(f,vldouble);}
710 if(t==DOUBLE){vldouble=zd2zld(p->vdouble);emitzld(f,vldouble);}
711 if(t==LDOUBLE){emitzld(f,p->vldouble);}
712 if(t==INT){vmax=zi2zm(p->vint);emitzm(f,vmax);}
713 if(t==(UNSIGNED|INT)){vumax=zui2zum(p->vuint);emitzum(f,vumax);}
714 if(t==LONG){vmax=zl2zm(p->vlong);emitzm(f,vmax);}
715 if(t==(UNSIGNED|LONG)){vumax=zul2zum(p->vulong);emitzum(f,vumax);}
716 if(t==LLONG){vmax=zll2zm(p->vllong);emitzm(f,vmax);}
717 if(t==(UNSIGNED|LLONG)){vumax=zull2zum(p->vullong);emitzum(f,vumax);}
718 if(t==MAXINT){emitzm(f,p->vmax);}
719 if(t==(UNSIGNED|MAXINT)){emitzum(f,p->vumax);}
720 /*FIXME*/
721 if(t==POINTER){vumax=zul2zum(p->vulong);emitzum(f,vumax);}
722}
723#endif
724
725void pric2(FILE *f,IC *p)
726/* Gibt ein IC aus. */
727{
728 if(p->code>NOP) ierror(0);
729 if(p->next&&p->next->prev!=p) ierror(0);
730 if(p->code>=LABEL&&p->code<=BRA){
731 if(p->code==LABEL)
732 fprintf(f,"L%d",p->typf);
733 else{
734 fprintf(f,"\t%s L%d",ename[p->code],p->typf);
735 if(p->q1.flags){ fprintf(f,",");probj(f,&p->q1,0);}
736 }
737 if(p->code==LABEL&&(p->flags&LOOP_COND_TRUE)) fprintf(f," (while-loop)");
738 if(p->code==BRA&&(p->flags&LOOP_COND_TRUE)) fprintf(f," (to-loop-test)");
739 }else{
740 fprintf(f,"\t%s ",ename[p->code]);
741 if(p->typf&VOLATILE) fprintf(f,"volatile ");
742 if(p->typf&CONST) fprintf(f,"const ");
743 if(p->typf&UNSIGNED) fprintf(f,"unsigned ");
744 if(p->typf){
745 if(ISVECTOR(p->typf))
746 fprintf(f,"%s%d ",typname[VECTYPE(p->typf)&NQ],VECDIM(p->typf));
747 else
748 fprintf(f,"%s ",typname[p->typf&NQ]);
749 }
750 probj(f,&p->q1,q1typ(p));
751 if(p->q2.flags){fprintf(f,",");probj(f,&p->q2,q2typ(p));}
752 if(p->z.flags){fprintf(f,"->");probj(f,&p->z,ztyp(p));}
753 if(p->code==ASSIGN||p->code==PUSH||p->code==POP||p->code==CALL)
754 fprintf(f," size=%ld",zm2l(p->q2.val.vmax));
755 if((p->code==SAVEREGS||p->code==RESTOREREGS)&&p->q1.reg)
756 fprintf(f," except %s",regnames[p->q1.reg]);
757 if(p->code==CONVERT)
758 fprintf(f," from %s%s",(p->typf2&UNSIGNED)?"unsigned ":"",typname[p->typf2&NQ]);
759 if(p->code==LSHIFT||p->code==RSHIFT)
760 fprintf(f," shift-type %s%s",(p->typf2&UNSIGNED)?"unsigned ":"",typname[p->typf2&NQ]);
761 if(p->code==ADDI2P||p->code==SUBIFP||p->code==SUBPFP||p->code==ADDRESS)
762 fprintf(f," ptype=%s%s",(p->typf2&UNSIGNED)?"unsigned ":"",typname[p->typf2&NQ]);
763 if(p->code==ASSIGN||p->code==PUSH)
764 if(p->typf2) fprintf(f," align=%d\n",p->typf2);
765 }
766 if(p->code==CALL){
767 fprintf(f," =>");
768 if(p->call_cnt==0)
769 fprintf(f,"(unknown)");
770 else{
771 int i;
772 for(i=0;i<p->call_cnt;i++)
773 fprintf(f," %s",p->call_list[i].v->identifier);
774 }
775
776 }
777 if(p->flags&EFF_IC) fprintf(f," (eff_ic)");
778 fprintf(f,"\n");
779#if 0
780 if(p->code==CALL){
781 int i;
782 //fprintf(f,"c=%p\n",p);
783 for(i=0;i<p->arg_cnt;i++){
784 //fprintf(f,"%p!\n",p->arg_list[i]);
785 fprintf(f,"%02d:",i);
786 pric2(f,p->arg_list[i]);
787 }
788 }
789#endif
790}
791void pric(FILE *f,IC *p)
792/* Gibt IC-Liste auf dem Bildschirm aus. */
793{
794 while(p){
795 pric2(f,p);
796/* if(p->q1.am||p->q2.am||p->z.am) ierror(0);*/
797 p=p->next;
798 }
799}
800void printzm(FILE *f,zmax x)
801/* Konvertiert zmax nach ASCII. */
802/* Basiert noch einigermassen auf */
803/* Zweierkomplementdarstellung (d.h. -MIN>MAX). */
804/* Ausserdem muss max(abs(max))<=max(unsigned max). */
805{
806 zmax zm;zumax zum;
807 zm=l2zm(0L);
808 if(zmleq(x,zm)&&!zmeqto(x,zm)){
809 fprintf(f,"-");zm=zum2zm(t_max(MAXINT));
810 if(zmleq(x,zmsub(l2zm(0L),zm))&&!zmeqto(x,zmsub(l2zm(0L),zm))){
811 /* aufpassen, da -x evtl. >LONG_MAX */
812 zum=t_max(MAXINT);
813 x=zmadd(x,zm);
814 }else
815 zum=ul2zum(0UL);
816 x=zmsub(l2zm(0L),x);
817 vumax=zm2zum(x);
818 zum=zumadd(zum,vumax);
819 }else
820 zum=zm2zum(x);
821 printzum(f,zum);
822}
823void printzum(FILE *f,zumax x)
824/* Konvertiert zumax nach ASCII. */
825{
826 zumax zum;unsigned long l;
827 zum=ul2zum(10UL);
828 if(!zumeqto(zumdiv(x,zum),ul2zum(0UL))) printzum(f,zumdiv(x,zum));
829 zum=zummod(x,zum);l=zum2ul(zum);
830 fprintf(f,"%c",(int)(l+'0'));
831}
832
833void printzld(FILE *f,zldouble x)
834/* Konvertiert zdouble nach ASCII, noch nicht fertig. */
835{
836 fprintf(f,"fp-constant");
837}
838void emitzm(FILE *f,zmax x)
839/* Konvertiert zmax nach ASCII. */
840/* Basiert noch einigermassen auf */
841/* Zweierkomplementdarstellung (d.h. -MIN>MAX). */
842/* Ausserdem muss max(abs(max))<=max(unsigned max). */
843{
844 zmax zm;zumax zum;
845 zm=l2zm(0L);
846 if(zmleq(x,zm)&&!zmeqto(x,zm)){
847 emit(f,"-");zm=zum2zm(t_max(MAXINT));
848 if(zmleq(x,zmsub(l2zm(0L),zm))&&!zmeqto(x,zmsub(l2zm(0L),zm))){
849 /* aufpassen, da -x evtl. >LONG_MAX */
850 zum=t_max(MAXINT);
851 x=zmadd(x,zm);
852 }else
853 zum=ul2zum(0UL);
854 x=zmsub(l2zm(0L),x);
855 vumax=zm2zum(x);
856 zum=zumadd(zum,vumax);
857 }else
858 zum=zm2zum(x);
859 emitzum(f,zum);
860}
861void emitzum(FILE *f,zumax x)
862/* Konvertiert zumax nach ASCII. */
863{
864 zumax zum;unsigned long l;
865 zum=ul2zum(10UL);
866 if(!zumeqto(zumdiv(x,zum),ul2zum(0UL))) emitzum(f,zumdiv(x,zum));
867 zum=zummod(x,zum);l=zum2ul(zum);
868 emit(f,"%c",(int)(l+'0'));
869}
870
871void emitzld(FILE *f,zldouble x)
872/* Konvertiert zdouble nach ASCII, noch nicht fertig. */
873{
874 emit(f,"fp-constant");
875}
876
877typedef struct memblock {struct memblock *next;void *p;} memblock;
878static memblock *first_mb;
879
880static void add_mb(void *p)
881{
882 memblock *mb_second=first_mb;
883 memblock *mb=malloc(sizeof(*mb));
884 if(!mb){
885 error(12);
886 raus();
887 }
888 first_mb=mb;
889 mb->next=mb_second;
890 mb->p=p;
891}
892
893static void remove_mb(void *p)
894{
895 memblock *mb_prev=0;
896 memblock *mb=first_mb;
897 while(mb){
898 if(mb->p==p){
899 if(mb_prev==0) first_mb=mb->next;
900 else mb_prev->next=mb->next;
901 (free)(mb);
902 return;
903 }
904 mb_prev=mb;
905 mb=mb->next;
906 }
907 ierror(0);
908}
909
910void *mymalloc(size_t size)
911/* Allocate memory and quit on failure. */
912{
913 void *p;
914 if(dmalloc)
915 size+=sizeof(size);
916 else if(size==0)
917 /* Not very nice, but simplest way to avoid a failure when size==0. */
918 size=1;
919 if(!(p=malloc(size))){
920 error(12);
921 raus();
922 }
923 if(DEBUG&32768){
924 printf("malloc %p (s=%lu)\n",p,(unsigned long)size);
925 fflush(stdout);
926 }
927 if(DEBUG&65536) add_mb(p);
928 if(dmalloc){
929 *(size_t *)p=size;
930 p=((char *)p)+sizeof(size);
931 memset(p,0xaa,size-sizeof(size));
932 }
933 return p;
934}
935
936void *myrealloc(void *p,size_t size)
937/* Reallocate memory and quit on failure. */
938{
939 void *new;
940 if(!p) return mymalloc(size);
941 if(dmalloc){
942 size+=sizeof(size);
943 new=realloc(((char *)p)-sizeof(size),size);
944 if(!new){
945 error(12);
946 raus();
947 }
948 if(DEBUG&32768){
949 printf("realloc %p to %p (s=%lu)\n",p,new,(unsigned long)size);
950 fflush(stdout);
951 }
952 if(DEBUG&65536){
953 remove_mb(p);
954 add_mb(new);
955 }
956 *(size_t *)new=size;
957 new=((char *)new)+sizeof(size);
958 return new;
959 }else{
960 new=realloc(p,size);
961 if(!new){
962 error(12);
963 raus();
964 }
965 if(DEBUG&32768){
966 printf("realloc %p to %p (s=%lu)\n",p,new,(unsigned long)size);
967 fflush(stdout);
968 }
969 if(DEBUG&65536){
970 remove_mb(p);
971 add_mb(new);
972 }
973 return new;
974 }
975}
976
977void myfree(void *p)
978{
979 if(p&&dmalloc){
980 p=((char*)p)-sizeof(size_t);
981 memset(p,0xbb,*(size_t *)(p));
982 }
983 if(DEBUG&32768){
984 printf("free %p\n",p);
985 fflush(stdout);
986 }
987 if((DEBUG&65536)&&p) remove_mb(p);
988 (free)(p); /* supp.h has #define free(x) myfree(x) */
989}
990
991char *mystrdup(char *p)
992{
993 char *new=mymalloc(strlen(p)+1);
994 strcpy(new,p);
995 return new;
996}
997
998/* Testet, ob zwei objs dieselben Register belegen. */
999int collides(obj *x,obj *y)
1000{
1001 int x1,x2,y1,y2;
1002 if(!(x->flags&REG)||!(y->flags&REG)) return 0;
1003 if(reg_pair(x->reg,&rp)){
1004 x1=rp.r1;x2=rp.r2;
1005 }else{
1006 x1=x->reg;x2=-1;
1007 }
1008 if(reg_pair(y->reg,&rp)){
1009 y1=rp.r1;y2=rp.r2;
1010 }else{
1011 y1=y->reg;y2=-2;
1012 }
1013 if(x1==y1||x1==y2||x2==y1||x2==y2)
1014 return 1;
1015 else
1016 return 0;
1017}
1018
1019/* Versucht, ein IC so zu drehen, dass q2 und z kein gemeinsames */
1020/* Register belegen. Liefert Null, wenn das nicht moeglich ist. */
1021int switch_IC(IC *p)
1022{
1023 int c;
1024 obj o;
1025 if(!collides(&p->q2,&p->z)) return 1;
1026 c=p->code;
1027 if((c<OR||c>AND)&&c!=ADD&&c!=MULT&&c!=ADDI2P) return 0;
1028 if(c==ADDI2P&&must_convert(q1typ(p),q2typ(p),0)) return 0;
1029 if(collides(&p->q1,&p->z)) return 0;
1030 o=p->q2;p->q2=p->q1;p->q1=o;
1031 return 1;
1032}
1033
1034void probj(FILE *f,obj *p,int t)
1035/* Gibt Objekt auf Bildschirm aus. */
1036{
1037 if(p->am){ fprintf(f,"[tgt-addressing-mode]");return;}
1038 if(p->flags&DREFOBJ){
1039 fprintf(f,"([");
1040 if(p->dtyp&CONST) fprintf(f,"const ");
1041 if(p->dtyp&VOLATILE) fprintf(f,"volatile ");
1042 if(p->dtyp&PVOLATILE) fprintf(f,"pvolatile ");
1043 fprintf(f,"%s]",typname[p->dtyp&NQ]);
1044 }
1045 if(p->flags&VARADR) fprintf(f,"#");
1046 if(p->flags&VAR) {
1047 if(!(p->flags&REG))
1048 printval(f,&p->val,MAXINT);
1049 if(p->flags&REG){
1050 fprintf(f,"%s",regnames[p->reg]);
1051 }else if(p->v->storage_class==AUTO||p->v->storage_class==REGISTER){
1052 fprintf(f,"+%ld(FP)", zm2l(p->v->offset));
1053 }else{
1054 if(p->v->storage_class==STATIC){
1055 fprintf(f,"+L%ld",zm2l(p->v->offset));
1056 }else{
1057 fprintf(f,"+_%s",p->v->identifier);
1058 }
1059 }
1060 if(*p->v->identifier)
1061 fprintf(f,"(%s)",p->v->identifier);
1062 else if(p->v->description)
1063 fprintf(f,"(%s)",p->v->description);
1064 else
1065 fprintf(f,"(%p)",(void *)p->v);
1066 if(p->v->reg) fprintf(f,":%s",regnames[abs(p->v->reg)]);
1067 }
1068 if((p->flags&REG)&&!(p->flags&VAR)) fprintf(f,"%s",regnames[p->reg]);
1069 if(p->flags&KONST){
1070 fprintf(f,"#");
1071 if(p->flags&DREFOBJ)
1072 printval(f,&p->val,p->dtyp&NU);
1073 else
1074 printval(f,&p->val,t&NU);
1075 }
1076 if(p->flags&SCRATCH) fprintf(f,"[S]");
1077 if(p->flags&DREFOBJ) fprintf(f,")");
1078}
1079void prl(FILE *o,struct_declaration *p)
1080/* Gibt eine struct_declaration auf dem Bildschirm aus. */
1081{
1082 int i;
1083 static int recurse=2;
1084 int merk_recurse=recurse;
1085 --recurse;
1086#ifdef HAVE_ECPP
1087/* removed */
1088/* removed */
1089/* removed */
1090/* removed */
1091/* removed */
1092/* removed */
1093/* removed */
1094/* removed */
1095/* removed */
1096/* removed */
1097/* removed */
1098/* removed */
1099/* removed */
1100/* removed */
1101/* removed */
1102/* removed */
1103#endif
1104 for(i=0;i<p->count;i++){
1105 fprintf(o," %d.:",i);
1106 if(recurse>=0){
1107 if((*p->sl)[i].identifier)fprintf(o," ident: %s; ",(*p->sl)[i].identifier);
1108 prd(o,(*p->sl)[i].styp);
1109 }
1110 }
1111 recurse=merk_recurse;
1112}
1113void prd(FILE *o,type *p)
1114/* Gibt einen Typ auf dem Bildschirm aus. */
1115{
1116 int f;
1117 if(!p) {fprintf(o,"empty type ");return;}
1118 f=p->flags;
1119/* fprintf(o,"(Sizeof=%ld,flags=%d)",zl2l(szof(p)),f);*/
1120/* if(type_uncomplete(p)) {fprintf(o,"incomplete ");}*/
1121 if(f&CONST) {fprintf(o,"const ");f&=~CONST;}
1122 if(f&STRINGCONST) {fprintf(o,"string-const ");f&=~STRINGCONST;}
1123 if(f&VOLATILE) {fprintf(o,"volatile ");f&=~VOLATILE;}
1124 if(f&UNSIGNED) {fprintf(o,"unsigned ");f&=~UNSIGNED;}
1125 if(p->attr) fprintf(o,"attr(%s) ",p->attr);
1126 if(p->reg) fprintf(o,"reg(%s) ",regnames[p->reg]);
1127 if(ISFUNC(f)){
1128 fprintf(o,"%s with parameters (",typname[f&NQ]);
1129 prl(o,p->exact);
1130 fprintf(o,") returning ");prd(o,p->next);return;
1131 }
1132 if(ISSTRUCT(f)||ISUNION(f)){
1133 fprintf(o,"%s with components {",typname[f&NQ]);
1134 prl(o,p->exact); fprintf(o,"} ");
1135 return;
1136 }
1137 if(ISPOINTER(f)) {fprintf(o,"%s to ",typname[f&NQ]);prd(o,p->next);return;}
1138 if(ISARRAY(f)) {fprintf(o,"%s [size %ld] of ",typname[f&NQ],zm2l(p->size));prd(o,p->next);return;}
1139 if(ISVECTOR(f)) {fprintf(o,"vector [size %ld] of %s",zm2l(p->size),typname[VECTYPE(f)&NQ]);return;}
1140
1141 fprintf(o,"%s",typname[f&NQ]);
1142}
1143void print_var(FILE *o,Var *p)
1144/* Gibt eine Variable aus. */
1145{
1146 if(p->identifier&&*p->identifier){
1147 fprintf(o, "ident: %s: ", p->identifier);
1148 }
1149 prd(o, p->vtyp);
1150}
1151
1152/* returns the first base Type in an compound type */
1153int get_first_base_type(type *t)
1154{
1155 if (!t) return 0;
1156 if (ISARRAY(t->flags)) {
1157 return get_first_base_type(t->next);
1158 } else if ((ISSTRUCT(t->flags)) || (ISUNION(t->flags))) {
1159 return get_first_base_type((*t->exact->sl)[0].styp);
1160 } else return t->flags;
1161}
1162
1163
1164#ifndef HAVE_EXT_TYPES
1165
1166void insert_const(union atyps *p,int t)
1167/* Traegt Konstante in entprechendes Feld ein. */
1168{
1169 if(!p) ierror(0);
1170 t&=NU;
1171 if(t==CHAR) {p->vchar=vchar;return;}
1172 if(t==SHORT) {p->vshort=vshort;return;}
1173 if(t==INT) {p->vint=vint;return;}
1174 if(t==LONG) {p->vlong=vlong;return;}
1175 if(t==LLONG) {p->vllong=vllong;return;}
1176 if(t==MAXINT) {p->vmax=vmax;return;}
1177 if(t==(UNSIGNED|CHAR)) {p->vuchar=vuchar;return;}
1178 if(t==(UNSIGNED|SHORT)) {p->vushort=vushort;return;}
1179 if(t==(UNSIGNED|INT)) {p->vuint=vuint;return;}
1180 if(t==(UNSIGNED|LONG)) {p->vulong=vulong;return;}
1181 if(t==(UNSIGNED|LLONG)) {p->vullong=vullong;return;}
1182 if(t==(UNSIGNED|MAXINT)) {p->vumax=vumax;return;}
1183 if(t==FLOAT) {p->vfloat=vfloat;return;}
1184 if(t==DOUBLE) {p->vdouble=vdouble;return;}
1185 if(t==LDOUBLE) {p->vldouble=vldouble;return;}
1186 if(t==POINTER) {p->vulong=vulong;return;}
1187}
1188void eval_const(union atyps *p,int t)
1189/* Weist bestimmten globalen Variablen Wert einer CEXPR zu. */
1190{
1191 int f=t&NQ;
1192 if(!p) ierror(0);
1193 if(f==MAXINT||(f>=CHAR&&f<=LLONG)){
1194 if(!(t&UNSIGNED)){
1195 if(f==CHAR) vmax=zc2zm(p->vchar);
1196 else if(f==SHORT)vmax=zs2zm(p->vshort);
1197 else if(f==INT) vmax=zi2zm(p->vint);
1198 else if(f==LONG) vmax=zl2zm(p->vlong);
1199 else if(f==LLONG) vmax=zll2zm(p->vllong);
1200 else if(f==MAXINT) vmax=p->vmax;
1201 else ierror(0);
1202 vumax=zm2zum(vmax);
1203 vldouble=zm2zld(vmax);
1204 }else{
1205 if(f==CHAR) vumax=zuc2zum(p->vuchar);
1206 else if(f==SHORT)vumax=zus2zum(p->vushort);
1207 else if(f==INT) vumax=zui2zum(p->vuint);
1208 else if(f==LONG) vumax=zul2zum(p->vulong);
1209 else if(f==LLONG) vumax=zull2zum(p->vullong);
1210 else if(f==MAXINT) vumax=p->vumax;
1211 else ierror(0);
1212 vmax=zum2zm(vumax);
1213 vldouble=zum2zld(vumax);
1214 }
1215 }else{
1216 if(ISPOINTER(f)){
1217 vumax=zul2zum(p->vulong);
1218 vmax=zum2zm(vumax);vldouble=zum2zld(vumax);
1219 }else{
1220 if(f==FLOAT) vldouble=zf2zld(p->vfloat);
1221 else if(f==DOUBLE) vldouble=zd2zld(p->vdouble);
1222 else vldouble=p->vldouble;
1223 vmax=zld2zm(vldouble);
1224 vumax=zld2zum(vldouble);
1225 }
1226 }
1227 vfloat=zld2zf(vldouble);
1228 vdouble=zld2zd(vldouble);
1229 vuchar=zum2zuc(vumax);
1230 vushort=zum2zus(vumax);
1231 vuint=zum2zui(vumax);
1232 vulong=zum2zul(vumax);
1233 vullong=zum2zull(vumax);
1234 vchar=zm2zc(vmax);
1235 vshort=zm2zs(vmax);
1236 vint=zm2zi(vmax);
1237 vlong=zm2zl(vmax);
1238 vllong=zm2zll(vmax);
1239}
1240#endif
1241
1242function_info *new_fi(void)
1243/* Belegt neue function_info-Struktur und initialisiert sie. */
1244{
1245 function_info *new;
1246 new=mymalloc(sizeof(*new));
1247 new->first_ic=new->last_ic=new->opt_ic=0;
1248 new->vars=0;
1249 new->statics=0;
1250 new->inline_asm=0;
1251 new->flags=0;
1252 new->call_cnt=new->use_cnt=new->change_cnt=0;
1253 new->call_list=new->use_list=new->change_list=0;
1254 memset(new->regs_modified,0,sizeof(new->regs_modified));
1255#if HAVE_OSEK
1256/* removed */
1257/* removed */
1258/* removed */
1259/* removed */
1260#endif
1261 new->stack1=ul2zum(0UL);
1262 new->stack2=ul2zum(0UL);
1263 new->inline_size=-1;
1264 new->inline_depth=0;
1265 return new;
1266}
1267void free_fi(function_info *p)
1268/* Gibt ein function_info mit Inhalt frei. */
1269{
1270 if(p->first_ic) free_IC(p->first_ic);
1271 if(p->opt_ic) free_IC(p->opt_ic);
1272 if(p->vars) free_var(p->vars);
1273 /* do not free statics */
1274 free(p->call_list);
1275 free(p->use_list);
1276 free(p->change_list);
1277 free(p->inline_asm);
1278 free(p);
1279}
1280
1281void print_fi(FILE *f,function_info *p)
1282/* Gibt function_info aus. */
1283{
1284 int i;
1285 fprintf(f,"function_info:\n");
1286 if(p->first_ic){
1287 IC *ic=p->first_ic;
1288 fprintf(f," inline_code:\n");
1289 pric2(f,ic);
1290 while(ic!=p->last_ic){
1291 ic=ic->next;
1292 pric2(f,ic);
1293 }
1294 }
1295 if(p->inline_asm)
1296 fprintf(f," inline_asm:\n%s\n",p->inline_asm);
1297 if(p->flags&ALL_CALLS)
1298 fprintf(f," all calls have been evaluated\n");
1299 if(p->flags&ALL_USES)
1300 fprintf(f," all uses have been evaluated\n");
1301 if(p->flags&ALL_MODS)
1302 fprintf(f," all changes have been evaluated\n");
1303 if(p->flags&ALL_REGS){
1304 fprintf(f," all reg-changes have been evaluated\n");
1305 for(i=1;i<=MAXR;i++)
1306 if(BTST(p->regs_modified,i)) fprintf(f," %s\n",regnames[i]);
1307 }
1308 fprintf(f," call_list:\n");print_varlist(f,p->call_list,p->call_cnt);
1309 fprintf(f," use_list:\n");print_varlist(f,p->use_list,p->use_cnt);
1310 fprintf(f," change_list:\n");print_varlist(f,p->change_list,p->change_cnt);
1311 if(p->flags&ALL_STACK){
1312 fprintf(f,"stack1: ");printzum(f,p->stack1);fprintf(f,"\n");
1313 fprintf(f,"stack2: ");printzum(f,p->stack2);fprintf(f,"\n");
1314 }
1315 if(p->flags&NEVER_RETURNS)
1316 fprintf(f," never returns\n");
1317 if(p->flags&ALWAYS_RETURNS)
1318 fprintf(f," always returns\n");
1319 if(p->flags&NOSIDEFX)
1320 fprintf(f," no side effects\n");
1321}
1322
1323void print_varlist(FILE *f,varlist *p,int n)
1324{
1325 int i;
1326 char *s;
1327 for(i=0;i<n;i++){
1328 if(p[i].v) s=p[i].v->identifier; else s="<unknown>";
1329 fprintf(f," %s(%p), flags=%d\n",s,(void*)p[i].v,p[i].flags);
1330 }
1331}
1332
1333int is_const(type *t)
1334/* tested, ob ein Typ konstant (und damit evtl. in der Code-Section) ist */
1335{
1336 if(!(t->flags&(CONST|STRINGCONST))){
1337 do{
1338 if(t->flags&(CONST|STRINGCONST)) return(1);
1339 if((t->flags&NQ)!=ARRAY) return 0;
1340 t=t->next;
1341 }while(1);
1342 }else return 1;
1343}
1344
1345/* is object volatile? */
1346int is_volatile_obj(obj *o)
1347{
1348 if(o->flags&DREFOBJ){
1349 if(o->dtyp&(VOLATILE|PVOLATILE)){
1350 return 1;
1351 }
1352 if((o->flags&VAR)&&ISPOINTER(o->v->vtyp->flags)&&(o->v->vtyp->next->flags&VOLATILE)){
1353 return 1;
1354 }
1355 }
1356 if(o->flags&VAR){
1357 return o->v->vtyp->flags&VOLATILE;
1358 }else{
1359 return 0;
1360 }
1361}
1362
1363/* is IC volatile? */
1364int is_volatile_ic(IC *p)
1365{
1366 if(p->q1.flags){
1367 if(is_volatile_obj(&p->q1)||(q1typ(p)&VOLATILE)) return 1;
1368 }
1369 if(p->q2.flags){
1370 if(is_volatile_obj(&p->q2)||(q2typ(p)&VOLATILE)) return 1;
1371 }
1372 if(p->z.flags){
1373 if(is_volatile_obj(&p->z)||(ztyp(p)&VOLATILE)) return 1;
1374 }
1375 return 0;
1376}
1377
1378/* removes last asm-line from emit-buffer */
1379void remove_asm(void)
1380{
1381 emit_l--;
1382 if(emit_l<0) emit_l=EMIT_BUF_DEPTH-1;
1383}
1384
1385/* flush the asm-output buffer */
1386void emit_flush(FILE *f)
1387{
1388 if(!f||no_emit) return;
1389 while(emit_f!=emit_l){
1390 fputs(emit_buffer[emit_f],f);
1391 emit_f++;
1392 if(emit_f>=EMIT_BUF_DEPTH) emit_f=0;
1393 }
1394 emit_l=emit_f=0;
1395 emit_p=emit_buffer[0];
1396}
1397
1398/* emit inline-asm, depending on no_inline_peephole, feed it through
1399 asm_peephole() or flush the buffer and print it directly to the file */
1400void emit_inline_asm(FILE *f,char *p)
1401{
1402 if(!f||no_emit) return;
1403 if(no_inline_peephole){
1404 emit_flush(f);
1405 fprintf(f,"%s\n",p);
1406 }else{
1407 while(*p){
1408 emit(f,"%c",*p++);
1409 }
1410 emit(f,"\n");
1411 }
1412}
1413
1414/* print output; this is only to be used for assembly output! */
1415void emit(FILE *f,const char *fmt,...)
1416{
1417 static char tmp[EMIT_BUF_LEN];
1418 char *p;
1419 va_list vl;
1420 if(!f||no_emit) return;
1421 va_start(vl,fmt);
1422 vsprintf(tmp,fmt,vl);
1423 p=tmp;
1424 while(*p){
1425 *emit_p++=*p++;
1426 if(p[-1]=='\n'){
1427 *emit_p=0;
1428#if HAVE_TARGET_PEEPHOLE
1429 while(emit_peephole());
1430#endif
1431 emit_l++;
1432 if(emit_l>=EMIT_BUF_DEPTH) emit_l=0;
1433 emit_p=emit_buffer[emit_l];
1434 if(emit_l==emit_f){
1435 /* FIXME: error check */
1436 fputs(emit_buffer[emit_f],f);
1437 emit_f++;
1438 if(emit_f>=EMIT_BUF_DEPTH) emit_f=0;
1439 }
1440 }
1441 }
1442 *emit_p=0;
1443}
1444
1445void emit_char(FILE *f,int c)
1446{
1447 static char tmp[2];
1448 tmp[0]=c;
1449 emit(f,tmp);
1450}
1451
1452/* detect whether the following code resembles a switch-case-statement */
1453/* will return the longest sequence which has at least min_density */
1454case_table *calc_case_table(IC *p,double min_density)
1455{
1456 static case_table ct;
1457 obj *o,*ccr;
1458 static union atyps *vals;
1459 union atyps min,max;
1460 zumax diff;
1461 static int *labels,cur_size;
1462 double cur_density;
1463 int t,j,num;
1464 if(p->code!=COMPARE||!(p->q2.flags&KONST))
1465 return 0;
1466 o=&p->q1;t=p->typf;
1467 if(!ISINT(t)||(t&VOLATILE)) return 0;
1468 num=0;
1469 ct.num=0;
1470 if(t&UNSIGNED){
1471 max.vumax=t_min(UNSIGNED|MAXINT);
1472 min.vumax=t_max(UNSIGNED|MAXINT);
1473 }else{
1474 max.vmax=t_min(MAXINT);
1475 min.vmax=t_max(MAXINT);
1476 }
1477 while(p&&p->code==COMPARE&&(p->q2.flags&KONST)&&p->typf==t&&objs_equal(o,&p->q1,t)){
1478 zumax zum;zmax zm;
1479 if(multiple_ccs) ccr=&p->z;
1480 if(num>=cur_size){
1481 cur_size+=64;
1482 labels=myrealloc(labels,cur_size*sizeof(*labels));
1483 vals=myrealloc(vals,cur_size*sizeof(*vals));
1484 }
1485 for(j=0;j<num;j++){
1486 if(!compare_const(&vals[j],&p->q2.val,t)){
1487 return 0; /* FIXME? Could simply ignore? */
1488 }
1489 }
1490 vals[num]=p->q2.val;
1491 p=p->next;
1492 while(p&&(p->code==NOP||p->code==ALLOCREG||p->code==FREEREG)) p=p->next;
1493 if(p->code!=BEQ||(multiple_ccs&&!objs_equal(ccr,&p->q1,0))) break;
1494 labels[num]=p->typf;
1495 p=p->next;
1496 while(p&&(p->code==NOP||p->code==ALLOCREG||p->code==FREEREG)) p=p->next;
1497 eval_const(&vals[num],t);
1498 num++;
1499 if(t&UNSIGNED){
1500 if(zumleq(vumax,min.vumax))
1501 insert_const(&min,UNSIGNED|MAXINT);
1502 if(zumleq(max.vumax,vumax))
1503 insert_const(&max,UNSIGNED|MAXINT);
1504 cur_density=num/(1+zld2d(zum2zld(zumsub(max.vumax,min.vumax))));
1505 if(cur_density>=min_density){
1506 ct.num=num;
1507 ct.next_ic=p;
1508 ct.min=min;
1509 ct.max=max;
1510 ct.diff=zumsub(max.vumax,min.vumax);
1511 ct.density=cur_density;
1512 }
1513 }else{
1514 if(zmleq(vmax,min.vmax))
1515 insert_const(&min,MAXINT);
1516 if(zmleq(max.vmax,vmax))
1517 insert_const(&max,MAXINT);
1518 cur_density=num/zld2d(zum2zld((1+zumsub(zm2zum(max.vmax),zm2zum(min.vmax)))));
1519 if(cur_density>=min_density){
1520 ct.num=num;
1521 ct.next_ic=p;
1522 ct.min=min;
1523 ct.max=max;
1524 ct.diff=zumsub(zm2zum(max.vmax),zm2zum(min.vmax));
1525 ct.density=cur_density;
1526 }
1527 }
1528 }
1529 ct.vals=vals;
1530 ct.labels=labels;
1531 ct.typf=t;
1532 return &ct;
1533}
1534
1535/* emit a list of jump-table entries */
1536void emit_jump_table(FILE *f,case_table *ct,char *da,char *labprefix,int defl)
1537{
1538 unsigned long l,e;
1539 int i;
1540 zmax zm;zumax zum;
1541 if(ct->typf&UNSIGNED){
1542 zum=ct->min.vumax;
1543 zm=zum2zm(zum);
1544 }else{
1545 zm=ct->min.vmax;
1546 zum=zm2zum(zm);
1547 }
1548 e=zum2ul(ct->diff);
1549 for(l=0;l<=e;l++){
1550 emit(f,"%s",da);
1551 for(i=0;i<ct->num;i++){
1552 eval_const(&ct->vals[i],ct->typf);
1553 if(zmeqto(vmax,zm)&&zumeqto(vumax,zum)){
1554 emit(f,"%s%d\n",labprefix,ct->labels[i]);
1555 break;
1556 }
1557 }
1558 if(i>=ct->num)
1559 emit(f,"%s%d\n",labprefix,defl);
1560 zm=zmadd(zm,l2zm(1L));
1561 zum=zumadd(zum,ul2zum(1UL));
1562 }
1563}
1564/* display warnings if specified stack-size cannot be guaranteed */
1565void static_stack_check(Var *v)
1566{
1567 /*FIXME*/
1568}
1569
1570#ifdef HAVE_REGPARMS
1571/* return the offset of the first variable-argument-macro to the
1572 beginning of the argument-area (i.e. the space occupied by
1573 normal arguments on the stack */
1574zmax va_offset(Var *v)
1575{
1576 int i;
1577 zmax offset=l2zm(0L);
1578 static type rp={0};
1579 treg_handle rh=empty_reg_handle;
1580 if((v->vtyp->next->flags&NQ)!=VOID&&!freturn(v->vtyp->next)){
1581 rp.next=v->vtyp->next;
1582 rp.flags=POINTER_TYPE(v->vtyp->next);
1583 if(!reg_parm(&rh,&rp,0,v->vtyp)){
1584 ierror(0);
1585 }
1586 }
1587 for(i=0;i<v->vtyp->exact->count;i++){
1588#if 0
1589 if((*v->vtyp->exact->sl)[i].reg!=0)
1590 continue;
1591#endif
1592 if(((*v->vtyp->exact->sl)[i].styp->flags&NQ)==VOID)
1593 ierror(0);
1594 if(reg_parm(&rh,(*v->vtyp->exact->sl)[i].styp,0,v->vtyp)!=0)
1595 continue;
1596 offset=zmadd(offset,szof((*v->vtyp->exact->sl)[i].styp));
1597 offset=zmmult(zmdiv(zmadd(offset,zmsub(stackalign,l2zm(1L))),stackalign),stackalign);
1598 }
1599 return offset;
1600}
1601#endif
1602
1603/* We provide an own qsort to get reproducable results. */
1604void vqsort (void *base,size_t nmemb,size_t size,int (*compar)(const void *,const void *))
1605{ char *base2=(char *)base;
1606 char tmp;
1607 size_t i,a,b,c;
1608 while(nmemb>1)
1609 { a=0;
1610 b=nmemb-1;
1611 c=(a+b)/2; /* Middle element */
1612 for(;;)
1613 { while((*compar)(&base2[size*c],&base2[size*a])>0)
1614 a++; /* Look for one >= middle */
1615 while((*compar)(&base2[size*c],&base2[size*b])<0)
1616 b--; /* Look for one <= middle */
1617 if(a>=b)
1618 break; /* We found no pair */
1619 for(i=0;i<size;i++) /* swap them */
1620 { tmp=base2[size*a+i];
1621 base2[size*a+i]=base2[size*b+i];
1622 base2[size*b+i]=tmp; }
1623 if(c==a) /* Keep track of middle element */
1624 c=b;
1625 else if(c==b)
1626 c=a;
1627 a++; /* These two are already sorted */
1628 b--;
1629 } /* a points to first element of right intervall now (b to last of left) */
1630 b++;
1631 if(b<nmemb-b) /* do recursion on smaller intervall and iteration on larger one */
1632 { vqsort(base2,b,size,compar);
1633 base2=&base2[size*b];
1634 nmemb=nmemb-b;
1635 }
1636 else
1637 { vqsort(&base2[size*b],nmemb-b,size,compar);
1638 nmemb=b; }
1639 }
1640 return;
1641}
1642
1643/* calculates registers used by this call IC
1644 returns 0 if not possible */
1645int calc_regs(IC *p,int showwarnings)
1646{
1647 int i;
1648 if(p->call_cnt){
1649 for(i=0;i<p->call_cnt;i++){
1650 if(p->call_list[i].v->fi&&(p->call_list[i].v->fi->flags&ALL_REGS)){
1651 bvunite(regs_modified,p->call_list[i].v->fi->regs_modified,RSIZE);
1652#if HAVE_OSEK
1653/* removed */
1654/* removed */
1655/* removed */
1656/* removed */
1657/* removed */
1658/* removed */
1659/* removed */
1660/* removed */
1661/* removed */
1662/* removed */
1663/* removed */
1664/* removed */
1665#endif
1666 }else{
1667 int r;
1668 for(r=1;r<=MAXR;r++) if(regscratch[r]) BSET(regs_modified,r);
1669 err_ic=p;
1670 if(!p->call_list[i].v->fi) p->call_list[i].v->fi=new_fi();
1671 if(!(p->call_list[i].v->fi->flags&WARNED_REGS)){
1672 error(318,p->call_list[i].v->identifier);
1673 p->call_list[i].v->fi->flags|=WARNED_REGS;
1674 }
1675 return 0;
1676 }
1677 }
1678 return 1;
1679 }
1680 err_ic=p;if(showwarnings) error(320);
1681 return 0;
1682}
1683
1684
1685
1686#ifndef HAVE_TARGET_BFLAYOUT
1687int bflayout(int bfoffset,int bfsize,int t)
1688{
1689 if(BIGENDIAN)
1690 return (int)zm2l(zmmult(sizetab[t&NQ],char_bit))-bfoffset-bfsize;
1691 else
1692 return bfoffset;
1693}
1694#endif
1695
1696long get_pof2(zumax x)
1697/* Yields log2(x)+1 oder 0. */
1698{
1699 zumax p;int ln=1,max=(int)zm2l(zmmult(sizetab[LLONG],char_bit));
1700 p=ul2zum(1L);
1701 while(ln<=max&&zumleq(p,x)){
1702 if(zumeqto(x,p)) return ln;
1703 ln++;p=zumadd(p,p);
1704 }
1705 return 0;
1706}
1707
1708/* check if type is a varargs function */
1709int is_varargs(type *t)
1710{
1711 int c;
1712 if(t->exact&&(c=t->exact->count)!=0&&(*t->exact->sl)[c-1].styp->flags!=VOID)
1713 return 1;
1714 else
1715 return 0;
1716}
1717
1718/* add string to type- oder variable-aatribute */
1719void add_attr(char **attr,char *new)
1720{
1721 int ln,lo;
1722 if(!new) return;
1723 if(*attr&&strstr(*attr,new)) return;
1724 if(add_attr_haddecl&&(!*attr||!strstr(*attr,new))) error(371,add_attr_haddecl->identifier,new);
1725 ln=strlen(new);
1726 if(*attr){
1727 lo=strlen(*attr);
1728 *attr=myrealloc(*attr,lo+ln+2);
1729 }else{
1730 lo=0;
1731 *attr=mymalloc(ln+2);
1732 }
1733 (*attr)[lo]=';';
1734 strcpy(*attr+lo+1,new);
1735}
1736
1737
1738hashtable *new_hashtable(size_t size)
1739{
1740 hashtable *new = mymalloc(sizeof(*new));
1741
1742 new->size = size;
1743 new->collisions = 0;
1744 new->entries = mymalloc(size*sizeof(*new->entries));
1745 memset(new->entries,0,size*sizeof(*new->entries));
1746 return new;
1747}
1748
1749size_t hashcode(char *name)
1750{
1751 size_t h = 5381;
1752 int c;
1753
1754 while (c = (unsigned char)*name++)
1755 h = ((h << 5) + h) + c;
1756 return h;
1757}
1758
1759/* add to hashtable; name must be unique */
1760void add_hashentry(hashtable *ht,char *name,hashdata data)
1761{
1762 size_t i=(hashcode(name)%ht->size);
1763 hashentry *new=mymalloc(sizeof(*new));
1764 new->name=name;
1765 new->data=data;
1766 if(DEBUG&1){
1767 if(ht->entries[i])
1768 ht->collisions++;
1769 }
1770 new->next=ht->entries[i];
1771 ht->entries[i]=new;
1772}
1773
1774/* finds unique entry in hashtable */
1775hashdata find_name(hashtable *ht,char *name)
1776{
1777 size_t i=hashcode(name)%ht->size;
1778 hashentry *p;
1779 for(p=ht->entries[i];p;p=p->next){
1780 if(!strcmp(name,p->name)){
1781 return p->data;
1782 }else
1783 ht->collisions++;
1784 }
1785 return 0;
1786}
1787
1788#ifndef CHARBACK
1789unsigned char CHARBACK(unsigned char x)
1790{
1791 static unsigned char tab[256],init=0;
1792 if(!init){
1793 int i,j;
1794 for(i=0;i<256;i++)
1795 for(j=0;j<256;j++)
1796 if(tab[j]==0&&CHARCONV(i)==j){
1797 tab[j&255]=i;
1798 break;
1799 }
1800 init=1;
1801 }
1802 return tab[x&255];
1803}
1804
1805void STRBACK(unsigned char *p)
1806{
1807 while(p&&*p){
1808 *p=CHARBACK(*p);
1809 p++;
1810 }
1811}
1812#endif
1813
1814int objs_equal(obj *o1,obj *o2,int t)
1815/* Vergleicht die beiden Objekte; liefert 1, wenn sie gleich sind, sonst 0 */
1816{
1817 int i1,i2;
1818 i1=o1->flags&~SCRATCH;i2=o2->flags&~SCRATCH;
1819 if(i1!=i2) return 0;
1820 if(i1&DREFOBJ){
1821 if(o1->dtyp!=o2->dtyp) return 0;
1822 }
1823 if(i1&KONST) return(!compare_const(&o1->val,&o2->val,t));
1824 if(i1&VAR){
1825 if(o1->v!=o2->v) return 0;
1826 if(!zmeqto(o1->val.vmax,o2->val.vmax)) return 0;
1827 }
1828 return 1;
1829}
1830
1831
1832#ifdef HAVE_MISRA
1833/* removed */
1834/* removed */
1835/* removed */
1836/* removed */
1837/* removed */
1838/* removed */
1839/* removed */
1840/* removed */
1841/* removed */
1842/* removed */
1843/* removed */
1844/* removed */
1845/* removed */
1846/* removed */
1847/* removed */
1848/* removed */
1849/* removed */
1850/* removed */
1851/* removed */
1852/* removed */
1853/* removed */
1854/* removed */
1855/* removed */
1856/* removed */
1857/* removed */
1858/* removed */
1859/* removed */
1860/* removed */
1861/* removed */
1862/* removed */
1863/* removed */
1864/* removed */
1865/* removed */
1866/* removed */
1867/* removed */
1868/* removed */
1869/* removed */
1870/* removed */
1871/* removed */
1872/* removed */
1873/* removed */
1874/* removed */
1875/* removed */
1876/* removed */
1877/* removed */
1878/* removed */
1879/* removed */
1880/* removed */
1881/* removed */
1882/* removed */
1883/* removed */
1884/* removed */
1885/* removed */
1886/* removed */
1887/* removed */
1888/* removed */
1889/* removed */
1890/* removed */
1891/* removed */
1892/* removed */
1893/* removed */
1894/* removed */
1895/* removed */
1896/* removed */
1897/* removed */
1898/* removed */
1899/* removed */
1900/* removed */
1901/* removed */
1902/* removed */
1903/* removed */
1904/* removed */
1905/* removed */
1906/* removed */
1907/* removed */
1908/* removed */
1909/* removed */
1910/* removed */
1911/* removed */
1912/* removed */
1913/* removed */
1914/* removed */
1915/* removed */
1916/* removed */
1917/* removed */
1918/* removed */
1919/* removed */
1920/* removed */
1921/* removed */
1922/* removed */
1923/* removed */
1924/* removed */
1925/* removed */
1926/* removed */
1927/* removed */
1928/* removed */
1929/* removed */
1930/* removed */
1931/* removed */
1932/* removed */
1933/* removed */
1934/* removed */
1935/* removed */
1936/* removed */
1937/* removed */
1938/* removed */
1939/* removed */
1940/* removed */
1941/* removed */
1942/* removed */
1943/* removed */
1944/* removed */
1945/* removed */
1946/* removed */
1947/* removed */
1948/* removed */
1949/* removed */
1950/* removed */
1951/* removed */
1952/* removed */
1953/* removed */
1954/* removed */
1955/* removed */
1956/* removed */
1957/* removed */
1958/* removed */
1959/* removed */
1960/* removed */
1961/* removed */
1962/* removed */
1963/* removed */
1964/* removed */
1965/* removed */
1966/* removed */
1967/* removed */
1968/* removed */
1969/* removed */
1970/* removed */
1971/* removed */
1972/* removed */
1973/* removed */
1974/* removed */
1975/* removed */
1976/* removed */
1977/* removed */
1978/* removed */
1979/* removed */
1980/* removed */
1981/* removed */
1982/* removed */
1983/* removed */
1984/* removed */
1985/* removed */
1986/* removed */
1987/* removed */
1988/* removed */
1989/* removed */
1990/* removed */
1991/* removed */
1992/* removed */
1993/* removed */
1994/* removed */
1995/* removed */
1996/* removed */
1997/* removed */
1998/* removed */
1999/* removed */
2000/* removed */
2001/* removed */
2002/* removed */
2003/* removed */
2004/* removed */
2005/* removed */
2006/* removed */
2007/* removed */
2008/* removed */
2009/* removed */
2010/* removed */
2011/* removed */
2012#endif