blob: 1bf274b5f1683b7bd04bc58f96704b6807a0555f [file] [log] [blame]
PulkoMandy17fc7592022-07-28 18:27:54 +02001#include "minicomp.h"
2
3#define clone_type clone_typ
4#define free_type freetyp
5#define new_icode new_IC
6#define add_icode add_IC
7#define free_all_icode() free_IC(first_ic)
8#define get_first_icode() first_ic
9typedef struct IC icode;
10
11static int errors;
12var *store_locals;
13
14struct rpair rp;
15
16char *copyright="minicomp/vbcc (c) in 2002 Volker Barthelmann";
17char *inname,*outname;
18struct struct_declaration *first_sd;
19struct Var *first_ext,*merk_varf;
20char **target_macros;
21
22FILE *out;
23
24void raus(void)
25{
26 var *v;
27 for(v=first_var[0];v;v=v->next)
28 if(v->type->flags!=FUNCTION){
29 gen_align(out,falign(v->type));
30 gen_var_head(out,v->vbccvar);
31 gen_ds(out,szof(v->type),v->type);
32 }
33
34 cleanup_cg(out);
35
36 if(errors>0)
37 exit(EXIT_FAILURE);
38 else
39 exit(EXIT_SUCCESS);
40}
41
42main(int argc,char **argv)
43{
44 int i,j,flag;
45 type *nt;
46
47 for(i=1;i<argc;i++){
48 if(*argv[i]!='-'){
49 if(inname)
50 error(18,"multiple input files");
51 inname=argv[i];
52 }else{
53 flag=0;
54 if((!strcmp("-o",argv[i]))&&i<argc-1){
55 flag=1;
56 outname=argv[++i];
57 continue;
58 }
59 if(!strncmp("-debug=",argv[i],7)){
60 flag=1;
61 sscanf(argv[i]+7,"%d",&j);
62 DEBUG=j;
63 continue;
64 }
65 if(!strncmp("-unroll-size=",argv[i],13)){
66 flag=1;
67 sscanf(argv[i]+13,"%d",&j);
68 unroll_size=j;
69 continue;
70 }
71 if(!strncmp("-inline-size=",argv[i],13)){
72 flag=1;
73 sscanf(argv[i]+13,"%d",&j);
74 inline_size=j;
75 continue;
76 }
77 if(!strncmp("-maxoptpasses=",argv[i],14)){
78 flag=1;
79 sscanf(argv[i]+14,"%d",&j);
80 maxoptpasses=j;
81 continue;
82 }
83 for(j=0;j<MAXGF&&flag==0;j++){
84 size_t l;
85 if(!g_flags_name[j]) continue;
86 l=strlen(g_flags_name[j]);
87 if(l>0&&!strncmp(argv[i]+1,g_flags_name[j],l)){
88 flag=1;
89 if((g_flags[j]&(USEDFLAG|FUNCFLAG))==USEDFLAG){error(19,"multiple option");break;}
90 g_flags[j]|=USEDFLAG;
91 if(g_flags[j]&STRINGFLAG){
92 if(argv[i][l+1]!='='){error(21,"string expected");}
93 if(argv[i][l+2]||i>=argc-1)
94 g_flags_val[j].p=&argv[i][l+2];
95 else
96 g_flags_val[j].p=&argv[++i][0];
97 }
98 if(g_flags[j]&VALFLAG){
99 if(argv[i][l+1]!='='){error(20,"value expected");}
100 if(argv[i][l+2]||i>=argc-1)
101 g_flags_val[j].l=atol(&argv[i][l+2]);
102 else
103 g_flags_val[j].l=atol(&argv[++i][0]);
104 }
105 if(g_flags[j]&FUNCFLAG) g_flags_val[j].f(&argv[i][l+1]);
106 }
107 }
108 if(!flag) error(23,"unknown option");
109 }
110 }
111
112 if(!inname)
113 error(22,"no input file");
114 infile=fopen(inname,"r");
115 if(!infile)
116 error(18,"could not open output file");
117 if(!outname)
118 error(23,"no output file");
119 out=fopen(outname,"w");
120 if(!out){
121 error(24,"could not open input file");
122 }
123 nt=new_type(FUNCTION);
124 nt->next=new_type(INT);
125 add_var("readInt",clone_type(nt));
126 add_var("writeInt",clone_type(nt));
127 add_var("writeChar",clone_type(nt));
128 add_var("readChar",clone_type(nt));
129 add_var("writeReal",nt);
130 nt=new_type(FUNCTION);
131 nt->next=new_type(REAL);
132 add_var("readReal",nt);
133
134 stackalign=l2zm(0L);
135 if(!init_cg()) exit(EXIT_FAILURE);
136 if(zmeqto(stackalign,l2zm(0L)))
137 stackalign=maxalign;
138 for(i=0;i<EMIT_BUF_DEPTH;i++)
139 emit_buffer[i]=mymalloc(EMIT_BUF_LEN);
140 emit_p=emit_buffer[0];
141
142 multiple_ccs=0;
143 optflags=-1;
144 maxoptpasses=100;
145
146 yyparse();
147
148 raus();
149}
150
151yyerror(char *s)
152{
153 error(1,s);
154}
155
156void error(int n,...)
157{
158 if(n==170||n==172) return;
159 errors++;
160 fprintf(stderr,"error %d\n",n);
161 raus();
162}
163
164void *getmem(size_t s)
165{
166 void *p=malloc(s);
167 if(!p){
168 error(2,"out of memory");
169 }
170 return p;
171}
172
173#define LABELNESTING 1024
174static int labelstack[LABELNESTING],labelidx;
175
176void push_int(int l)
177{
178 labelstack[labelidx++]=l;
179}
180
181int pop_int()
182{
183 return labelstack[--labelidx];
184}
185
186#define NAMENESTING 1024
187static char *namestack[NAMENESTING],nameidx;
188
189void push_ptr(void *ptr)
190{
191 namestack[nameidx++]=ptr;
192}
193
194void *pop_ptr()
195{
196 return namestack[--nameidx];
197}
198
199
200char *typename[]={" ","int","real","array","function"};
201
202
203type *new_type(int t)
204{
205 type *new=new_typ();
206 new->flags=t;
207 new->next=0;
208 return new;
209}
210
211type *new_array(type *t,node *p)
212{
213 type *new=new_typ();
214 simplify_tree(p);
215 if(p->flags!=NNUMBER)
216 error(3,"array size not a constant");
217 if(p->type->flags!=INT)
218 error(4,"array size not an integer");
219 new->flags=ARRAY;
220 new->next=t;
221 new->size=l2zm((long)p->ivalue);
222 free_tree(p);
223 return new;
224}
225
226int nesting;
227int local_offset,parm_offset,framesize;
228
229#define MAXNESTING 128
230var *first_var[128];
231
232void free_varlist(var *v)
233{
234 var *m;
235 while(v){
236 free_var(v->vbccvar);
237 m=v->next;
238 free(v);
239 v=m;
240 }
241}
242
243void enter_block()
244{
245 nesting++;
246 first_var[nesting]=0;
247 push_int(local_offset);
248}
249
250void leave_block()
251{
252 if(first_var[nesting]){
253 var *p=first_var[nesting];
254 while(p->next)
255 p=p->next;
256 p->next=store_locals;
257 p->vbccvar->next=merk_varf;
258 store_locals=first_var[nesting];
259 merk_varf=store_locals->vbccvar;
260 }
261 nesting--;
262 local_offset=pop_int();
263}
264
265void gen_func(var *v,icode *first,int framesize)
266{
267 pric(stdout,get_first_icode());
268 vl1=first_var[0]?first_var[0]->vbccvar:0;
269 vl2=first_var[1]?first_var[1]->vbccvar:0;
270 vl3=merk_varf;
271 optimize(optflags,v->vbccvar);
272 memset(regs_modified,0,RSIZE);
273 pric(stdout,get_first_icode());
274 gen_code(out,get_first_icode(),v->vbccvar,max_offset);
275}
276
277void enter_func(char *name,type *p)
278{
279 type *t=new_type(FUNCTION);
280 var *v;
281 t->next=p;
282 t->exact=getmem(sizeof(*t->exact));
283 t->exact->count=0;
284 v=add_var(name,t);
285 local_offset=parm_offset=framesize=0;
286 push_ptr(v);
287 enter_block();
288}
289
290void leave_func()
291{
292 icode *p,*merk;
293 leave_block();
294 gen_func(pop_ptr(),get_first_icode(),framesize);
295 free_all_icode();
296 first_ic=last_ic=0;
297 free_varlist(store_locals);
298 merk_varf=0;
299 store_locals=0;
300}
301
302var *find_var(char *p,int minnest)
303{
304 var *v;
305 int i;
306
307 for(i=nesting;i>=minnest;i--){
308 for(v=first_var[i];v;v=v->next)
309 if(!strcmp(v->name,p))
310 return v;
311 }
312 return 0;
313}
314
315var *add_var(char *name,type *t)
316{
317 var *new=getmem(sizeof(*new));
318 struct Var *vv;
319 /*FIXME: add vbccvar */
320 if(find_var(name,nesting))
321 error(5,"var %s already defined",name);
322 new->nesting=nesting;
323 new->name=add_string(name);
324 new->type=t;
325 if(*name==0){
326 new->next=store_locals;
327 }else{
328 new->next=first_var[nesting];
329 }
330 if(nesting==1){
331 /* parameter */
332 new->offset=parm_offset;
333 parm_offset+=szof(t);
334 }
335 if(nesting>1){
336 /* local variable */
337 new->offset=local_offset;
338 local_offset+=szof(t);
339 if(local_offset>framesize)
340 framesize=local_offset;
341 }
342 /* attach vbcc variable */
343 vv=new_var();
344 vv->vtyp=clone_typ(new->type);
345 vv->identifier=add_string(name);
346 vv->nesting=(*name!=0?nesting:2);
347 vv->storage_class=(vv->nesting==0?EXTERN:AUTO);
348 if(nesting==1)
349 vv->offset=zmsub(l2zm(0L),zmadd(maxalign,l2zm(new->offset)));
350 else
351 vv->offset=l2zm((long)local_offset);
352 new->vbccvar=vv;
353
354 if(*name==0){
355 store_locals=new;
356 vv->next=merk_varf;
357 merk_varf=vv;
358 }else{
359 vv->next=first_var[nesting]?first_var[nesting]->vbccvar:0;
360 first_var[nesting]=new;
361 }
362 return new;
363}
364
365var *new_temp(int tflags)
366{
367 char tname[16];
368 static int itmps,rtmps,ptmps;
369 if(tflags==INT)
370 sprintf(tname,"\0 itmp%d",++itmps);
371 else if(tflags==REAL)
372 sprintf(tname,"\0 rtmp%d",++rtmps);
373 else if(tflags==POINTER)
374 sprintf(tname,"\0 rtmp%d",++ptmps);
375 else
376 error(16,"internal");
377 return add_var(tname,new_type(tflags));
378}
379
380struct Var *add_tmp_var(struct Typ *t)
381{
382
383 return new_temp(t->flags)->vbccvar;
384}
385
386char *add_string(char *s)
387{
388 char *new=getmem(strlen(s)+1);
389 strcpy(new,s);
390 return new;
391}
392
393char *nodename[]={
394 "var","number","add","mul","sub","div","index","equals",
395 "lt","gt","leq","geq","neq","and","or",
396 "int2real","real2int","assign","call","argument"
397};
398
399node *number_node(void)
400{
401 node *new=getmem(sizeof(*new));
402 new->flags=NNUMBER;
403 if(strstr(tkname,".")){
404 double rval;
405 sscanf(tkname,"%lf",&rval);
406 new->rvalue=rval;
407 new->type=new_type(REAL);
408 new->left=new->right=0;
409 }else{
410 new->ivalue=atoi(tkname);
411 new->type=new_type(INT);
412 new->left=new->right=0;
413 }
414 return new;
415}
416
417node *var_node(void)
418{
419 var *v=find_var(tkname,0);
420 node *new;
421 if(!v){
422 error(6,"unknown identifier: %s",tkname);
423 }
424 new=getmem(sizeof(*new));
425 new->flags=NVARIABLE;
426 new->var=v;
427 new->type=clone_type(v->type);
428 new->left=new->right=0;
429 return new;
430}
431
432
433node *binary_node(enum nodeflags flags,node *left,node *right)
434{
435 node *new=getmem(sizeof(*new));
436 new->flags=flags;
437 new->left=left;
438 new->right=right;
439 new->type=0;
440 if(!left||(flags!=NCALL&&!right))
441 error(7,"internal error");
442 if(flags==NINDEX){
443 if(left->type->flags!=ARRAY)
444 error(8,"operand of [] must be array");
445 new->type=clone_type(left->type->next);
446 }else if(flags==NARG){
447 /* nothing to do? */
448 }else if(flags==NCALL){
449 if(left->type->flags!=FUNCTION)
450 error(9,"only functions can be called");
451 new->type=clone_type(left->type->next);
452 }else{
453 if(left->type->flags==ARRAY||right->type->flags==ARRAY)
454 error(10,"both operands must be real or int");
455 if(left->type->flags==REAL||right->type->flags==REAL){
456 new->type=new_type(REAL);
457 if(left->type->flags==INT){
458 new->left=conv_tree(left,REAL);
459 }
460 if(right->type->flags==INT){
461 new->right=conv_tree(right,REAL);
462 }
463 }else
464 new->type=new_type(INT);
465 }
466 return new;
467}
468
469void print_tree(node *p)
470{
471 printf("%s(",nodename[p->flags]);
472 if(p->left)
473 print_tree(p->left);
474 if(p->right){
475 printf(",");
476 print_tree(p->right);
477 }
478 if(p->flags==NNUMBER){
479 if(p->type->flags==INT)
480 printf("%d[int]",p->ivalue);
481 else
482 printf("%g[real]",p->rvalue);
483 }
484 if(p->flags==NVARIABLE)
485 printf("%s[%s]",p->var->name,typename[p->var->type->flags]);
486 printf(")");
487}
488
489node *conv_tree(node *p,int tflags)
490{
491 node *new;
492 if(p->type->flags==tflags)
493 return p;
494 new=getmem(sizeof(*new));
495 if(tflags==REAL)
496 new->flags=NI2R;
497 else
498 new->flags=NR2I;
499 new->type=new_type(p->type->flags);
500 new->left=p;
501 new->right=0;
502 return new;
503}
504
505void free_tree(node *p)
506{
507 if(p->left)
508 free_tree(p->left);
509 if(p->right)
510 free_tree(p->right);
511 if(p->type)
512 free_type(p->type);
513 free(p);
514}
515
516
517static void const_node(node *p,int val)
518{
519 p->flags=NNUMBER;
520 p->ivalue=val;
521 if(p->left)
522 free_tree(p->left);
523 if(p->right)
524 free_tree(p->right);
525 p->left=p->right=0;
526}
527
528void simplify_tree(node *p)
529{
530 if(p->left)
531 simplify_tree(p->left);
532 if(p->right)
533 simplify_tree(p->right);
534 if(p->type&&p->type->flags==INT&&p->left&&p->left->flags==NNUMBER&&p->right&&p->right->flags==NNUMBER){
535 switch(p->flags){
536 case NADD: const_node(p,p->left->ivalue+p->right->ivalue); break;
537 case NMUL: const_node(p,p->left->ivalue*p->right->ivalue); break;
538 case NSUB: const_node(p,p->left->ivalue-p->right->ivalue); break;
539 case NDIV:
540 if(p->right->ivalue!=0)
541 const_node(p,p->left->ivalue/p->right->ivalue); break;
542 }
543 }
544}
545
546void assign_statement(node *left,node *right)
547{
548 if(left->type->flags==ARRAY||right->type->flags==ARRAY)
549 error(11,"array type in assignment");
550 if(left->type->flags==FUNCTION||right->type->flags==FUNCTION)
551 error(12,"function type in assignment");
552
553 right=conv_tree(right,left->type->flags);
554 simplify_tree(left);
555 simplify_tree(right);
556 if(left->flags==NINDEX){
557 icode *n1,*n2,*n3;
558 n1=new_icode();
559 n1->code=MULT;
560 n1->typf=INT;
561 n1->q1=*gen_tree(left->right);
562 n1->q2.flags=KONST;
563 n1->q2.val.vint=zm2zi(sizetab[INT]);
564 n1->z.flags=VAR;
565 n1->z.v=new_temp(INT)->vbccvar;
566 n1->z.val.vmax=l2zm(0L);
567 n2=new_icode();
568 n2->code=ADDI2P;
569 n2->typf=INT;
570 n2->typf2=POINTER;
571 n2->q1=*gen_tree(left->left);
572 n2->q2=n1->z;
573 n2->z.flags=VAR;
574 n2->z.v=new_temp(POINTER)->vbccvar;
575 n2->z.val.vmax=l2zm(0L);
576 n3=new_icode();
577 n3->code=ASSIGN;
578 n3->typf=left->type->flags;
579 n3->q1=*gen_tree(right);
580 n3->z=n2->z;
581 n3->z.flags|=DREFOBJ;
582 n3->z.dtyp=POINTER;
583 n3->q2.val.vmax=szof(left->type);
584 add_icode(n1);
585 add_icode(n2);
586 add_icode(n3);
587#if 0
588 /* leicht anderes Format */
589 new->flags=CSTORE;
590 new->op1=*gen_tree(right);
591 new->op2=*gen_tree(left->left);
592 new->dest=*gen_tree(left->right);
593#endif
594 }else{
595 icode *new=new_icode();
596 new->code=ASSIGN;
597 new->q1=*gen_tree(right);
598 new->z=*gen_tree(left);
599 new->q2.val.vmax=szof(left->type);
600 new->typf=left->type->flags;
601 add_icode(new);
602 }
603 free_tree(left);
604 free_tree(right);
605}
606
607void return_statement(node *p)
608{
609 icode *new=new_icode();
610 p=conv_tree(p,INT); /*FIXME*/
611 simplify_tree(p);
612 new->code=SETRETURN;
613 new->typf=p->type->flags;
614 new->q1=*gen_tree(p);
615 new->z.reg=freturn(p->type);
616 add_icode(new);
617 free_tree(p);
618}
619
620void while_statement(node *p)
621{
622 int loop=++label,exit=++label;
623 simplify_tree(p);
624 gen_cond(p,loop,exit);
625 gen_label(loop);
626 last_ic->flags|=LOOP_COND_TRUE;
627 push_ptr(p);
628 push_int(loop);
629 push_int(exit);
630#if 0
631 gen_label(loop);
632 gen_cond(p,start,exit);
633 free_tree(p);
634 gen_label(start);
635 push_int(loop);
636 push_int(exit);
637#endif
638}
639
640void while_end()
641{
642 int loop,exit;
643 node *p;
644 exit=pop_int();
645 loop=pop_int();
646 p=pop_ptr();
647 gen_cond(p,loop,exit);
648 gen_label(exit);
649#if 0
650 new=new_icode();
651 new->code=BRA;
652 new->typf=loop;
653 add_icode(new);
654 gen_label(exit);
655#endif
656}
657
658void if_statement(node *p)
659{
660 int true=++label,false=++label;
661 simplify_tree(p);
662 gen_cond(p,true,false);
663 free_tree(p);
664 gen_label(true);
665 push_int(false);
666}
667
668void if_end()
669{
670 gen_label(pop_int());
671}
672
673void if_else()
674{
675 int endlabel=++label;
676 icode *new=new_icode();
677 new->code=BRA;
678 new->typf=++label;
679 add_icode(new);
680 gen_label(pop_int());
681 push_int(label);
682}
683
684int label;
685
686operand *gen_tree(node *p)
687{
688 icode *new;
689 static operand op;
690
691 if(p->flags==NVARIABLE){
692 if(p->var->type->flags==ARRAY){
693 if(p->var->nesting==0){
694 op.flags=VAR|VARADR;
695 op.v=p->var->vbccvar;
696 op.val.vmax=l2zm(0L);
697 return &op;
698 }else{
699 icode *new=new_icode();
700 new->flags=ADDRESS;
701 new->q1.flags=VAR;
702 new->q1.v=p->var->vbccvar;
703 new->q1.val.vmax=l2zm(0L);
704 new->z.flags=VAR;
705 new->z.v=new_temp(POINTER)->vbccvar;
706 new->z.val.vmax=l2zm(0L);
707 add_icode(new);
708 return &new->z;
709 }
710 }else{
711 op.flags=VAR;
712 op.v=p->var->vbccvar;
713 op.val.vmax=l2zm(0L);
714 return &op;
715 }
716 }
717
718 if(p->flags==NNUMBER){
719 op.flags=KONST;
720 if(p->type->flags==INT)
721 op.val.vint=p->ivalue;
722 else
723 op.val.vdouble=zld2zd(d2zld(p->rvalue));
724 return &op;
725 }
726
727 if(p->flags==NADD||p->flags==NMUL||p->flags==NSUB||p->flags==NDIV||p->flags==NI2R||p->flags==NR2I){
728 int ttyp=p->type->flags;
729 new=new_icode();
730 switch(p->flags){
731 case NADD: new->code=ADD;break;
732 case NMUL: new->code=MULT;break;
733 case NSUB: new->code=SUB;break;
734 case NDIV: new->code=DIV;break;
735 case NI2R: new->code=CONVERT;ttyp=REAL;new->typf2=INT;break;
736 case NR2I: new->code=CONVERT;ttyp=INT;new->typf2=REAL;break;
737 }
738 new->q1=*gen_tree(p->left);
739 if(p->right)
740 new->q2=*gen_tree(p->right);
741 new->z.flags=VAR;
742 new->z.v=new_temp(ttyp)->vbccvar;
743 new->z.val.vmax=l2zm(0L);
744 new->typf=ttyp;
745 add_icode(new);
746 return &new->z;
747 }
748
749 if(p->flags==NINDEX){
750 if(p->type->flags==ARRAY){
751 icode *merk,*new=new_icode();
752 new->flags=MULT;
753 new->typf=INT;
754 new->q1=*gen_tree(p->right);
755 new->q2.flags=KONST;
756 new->q2.val.vint=szof(p->type);
757 new->z.flags=VAR;
758 new->z.v=new_temp(INT)->vbccvar;
759 new->z.val.vmax=l2zm(0L);
760 add_icode(new);
761 merk=new;
762 new=new_icode();
763 new->flags=ADDI2P;
764 new->typf=INT;
765 new->typf2=POINTER;
766 new->q1=*gen_tree(p->left);
767 new->q2=merk->z;
768 new->z.flags=VAR;
769 new->z.v=new_temp(POINTER)->vbccvar;
770 new->z.val.vmax=l2zm(0L);
771 op=new->z;
772 add_icode(new);
773 return &new->z;
774 }else{
775 icode *merk,*new=new_icode();
776 new->code=MULT;
777 new->typf=INT;
778 new->q1=*gen_tree(p->right);
779 new->q2.flags=KONST;
780 new->q2.val.vint=zm2zi(sizetab[INT]);
781 new->z.flags=VAR;
782 new->z.v=new_temp(INT)->vbccvar;
783 new->z.val.vmax=l2zm(0L);
784 add_icode(new);
785 merk=new;
786 new=new_icode();
787 new->code=ADDI2P;
788 new->q1=*gen_tree(p->left);
789 new->q2=merk->z;
790 new->typf=INT;
791 new->typf2=POINTER;
792 new->z.flags=VAR;
793 new->z.v=new_temp(POINTER)->vbccvar;
794 new->z.val.vmax=l2zm(0L);
795 op=new->z;
796 op.flags|=DREFOBJ;
797 op.dtyp=POINTER;
798 add_icode(new);
799 return &op;
800 }
801 }
802
803 if(p->flags==NCALL){
804 icode *new=new_icode();
805 new->code=CALL;
806 new->typf=FUNKT;
807 if(p->right)
808 new->q2.val.vmax=l2zm(push_arg(p->right));
809 else
810 new->q2.val.vmax=l2zm(0L);
811 new->q1=*gen_tree(p->left);
812 add_icode(new);
813 new=new_icode();
814 new->code=GETRETURN;
815 new->z.flags=VAR;
816 new->typf=p->type->flags;
817 new->z.v=new_temp(p->type->flags)->vbccvar;
818 new->z.val.vmax=l2zm(0L);
819 new->q1.reg=freturn(p->type);
820 add_icode(new);
821 return &new->z;
822 }
823
824 error(13,"operation not yet supported");
825}
826
827void gen_label(int l)
828{
829 icode *new=new_icode();
830 new->code=LABEL;
831 new->typf=l;
832 add_icode(new);
833}
834
835void gen_cond(node *p,int true_label,int false_label)
836{
837 icode *new;
838 if(p->flags==NAND){
839 int tmp=++label;
840 gen_cond(p->left,tmp,false_label);
841 gen_label(tmp);
842 gen_cond(p->right,true_label,false_label);
843 return;
844 }
845 if(p->flags==NOR){
846 int tmp=++label;
847 gen_cond(p->left,true_label,tmp);
848 gen_label(tmp);
849 gen_cond(p->right,true_label,false_label);
850 return;
851 }
852 new=new_icode();
853 new->code=COMPARE;
854 new->typf=p->type->flags;
855 new->q1=*gen_tree(p->left);
856 new->q2=*gen_tree(p->right);
857 add_icode(new);
858 new=new_icode();
859 switch(p->flags){
860 case NEQUALS: new->code=BEQ;break;
861 case NNEQ: new->code=BNE;break;
862 case NLT: new->code=BLT;break;
863 case NGT: new->code=BGT;break;
864 case NLEQ: new->code=BLE;break;
865 case NGEQ: new->code=BGE;break;
866 default: error(14,"internal");
867 }
868 new->typf=true_label;
869 add_icode(new);
870
871 new=new_icode();
872 new->code=BRA;
873 new->typf=false_label;
874 add_icode(new);
875}
876
877int push_arg(node *p)
878{
879 if(p->flags==NARG){
880 int s;
881 s=push_arg(p->right);
882 return s+push_arg(p->left);
883 }else{
884 icode *new=new_icode();
885 if(p->type->flags==ARRAY)
886 error(15,"arrays cannot be passed");
887 new->code=PUSH;
888 new->q2.val.vmax=szof(p->type);
889 new->z.val.vmax=new->q2.val.vmax;
890 new->typf=p->type->flags;
891 new->q1=*gen_tree(p);
892 add_icode(new);
893 return szof(p->type);
894 }
895}
896
897void free_var(struct Var *v)
898{
899 free(v);
900 /*FIXME*/
901}
902
903void add_IC(icode *new)
904{
905 if(last_ic&&new->code==ASSIGN&&new->q1.flags==VAR&&last_ic->z.flags==VAR&&
906 new->q1.v==last_ic->z.v&&zmeqto(new->q1.val.vmax,last_ic->z.val.vmax)&&
907 *new->q1.v->identifier==0){
908 last_ic->z=new->z;
909 free(new);
910 return;
911 }
912 insert_IC(last_ic,new);
913}