comparison mc-inline.c @ 462:f7c87020e6fe

inline
author kono
date Fri, 03 Dec 2004 01:05:17 +0900
parents
children 50a59dfb4606
comparison
equal deleted inserted replaced
461:2a49dfe59540 462:f7c87020e6fe
1 /* Micro-C Partial Evaluator Part */
2 /* $Id$ */
3
4 #include <stdio.h>
5 #include "mc.h"
6 #include "mc-parse.h"
7 #include "mc-codegen.h"
8 #include "mc-switch.h"
9
10
11 /*
12 Basic code generator from parse tree
13 */
14
15 extern void
16 st_decl(int e1){
17 // NMTBL *n = (NMTBL *)caddr(e1);
18 // int stmode = cadddr(e1);
19 }
20
21 extern void
22 st_if(int e1){
23 int l1,l2,slfree;
24 int e2=caddr(e1),e3;
25 // conv->if_();
26 slfree=lfree;
27 checkret();
28 l1 = bexpr(car(e2),0,fwdlabel());
29 // conv->if_then_();
30 g_expr_u(cadr(e2));
31 checkret();
32 if ((e3=caddr(e2))) { // else
33 // conv->if_else_();
34 if ((l2 = control))
35 gen_jmp(l2=fwdlabel());
36 fwddef(l1);
37 g_expr_u(e3);
38 checkret();
39 if (l2) fwddef(l2);
40 } else {
41 fwddef(l1);
42 }
43 // conv->if_endif_();
44 }
45
46
47 extern void
48 st_do(int e1){
49 int sbreak,scontinue,l;
50
51 sbreak=blabel;
52 scontinue=clabel;
53 blabel=fwdlabel();
54 clabel=fwdlabel();
55 control=1;
56 checkret();
57 l=backdef();
58 // conv->dowhile_();
59 g_expr_u(cadddr(e1));
60 checkret();
61 // conv->dowhile_cond_();
62 bexpr(caddr(e1),1,l);
63 // conv->dowhile_end_();
64 fwddef(blabel);
65 clabel=scontinue;
66 blabel=sbreak;
67 }
68
69
70 extern void
71 st_while(int e1){
72 int sbreak,scontinue,e;
73
74 sbreak=blabel;
75 scontinue=clabel;
76 blabel=fwdlabel();
77 control=1;
78 checkret();
79 clabel=backdef();
80 // conv->while_();
81 // conv->while_body_();
82 if(!(e=cadddr(e1))) {
83 bexpr(caddr(e1),1,clabel);
84 // conv->sm_();
85 } else {
86 bexpr(caddr(e1),0,blabel);
87 g_expr_u(e);
88 checkret();
89 if(control)
90 gen_jmp(clabel);
91 }
92 // conv->while_end_();
93 fwddef(blabel);
94 clabel=scontinue;
95 blabel=sbreak;
96 }
97
98
99 extern void
100 st_for(int e1){
101 int p0,p1,p2,body;
102 int l,e;
103 int sbreak=blabel;
104 int scontinue=clabel;
105
106 e = caddr(e1);
107 p0 = car(e); p1 = cadr(e); p2 = caddr(e); body = cadddr(e);
108
109 blabel=fwdlabel();
110 // conv->for_();
111 if (p0) {
112 checkret();
113 g_expr_u(p0);
114 }
115 // conv->for1_();
116 control=1;
117 checkret();
118 l=backdef();
119 if (p1) {
120 bexpr(p1,0,blabel);
121 }
122 // conv->for2_();
123 // conv->for_body_();
124 if (!p2) {
125 clabel=l;
126 g_expr_u(body);
127 checkret();
128 } else {
129 clabel=fwdlabel();
130 g_expr_u(body);
131 checkret();
132 fwddef(clabel);
133 g_expr_u(p2);
134 }
135 // conv->for_end_();
136 gen_jmp(l);
137 fwddef(blabel);
138 clabel=scontinue;
139 blabel=sbreak;
140 }
141
142
143 extern void
144 st_switch(int e1){
145 int sbreak,scase,sdefault,slfree,svalue,slist;
146
147 checkret();
148 slist = cslist;
149 cslist = 0;
150 sbreak=blabel; /* save parents break label */
151 blabel=fwdlabel();
152 sdefault=dlabel; /* save parents default label */
153 dlabel=0;
154 scase=cslabel; /* save parents next case label */
155 // conv->switch_();
156 slfree=lfree;
157 svalue=csvalue1; /* save parents switch value */
158 gexpr(caddr(e1),1);
159 csvalue1=csvalue() ;
160 // conv->switch_body_();
161 cslabel = control = 0;
162 g_expr_u(cadddr(e1));
163 // conv->switch_end_();
164 checkret();
165 #if CASE_CODE
166 if (control) gen_jmp(blabel);
167 genswitch(cslist,cslabel);
168 #else
169 if(dlabel) def_label(cslabel,dlabel);
170 else fwddef(cslabel);
171 #endif
172 csvalue1=svalue;
173 cslabel=scase;
174 dlabel=sdefault;
175 fwddef(blabel);
176 blabel=sbreak;
177 cslist = slist;
178 }
179
180
181 extern void
182 st_comp(int e1){
183 g_expr_u(caddr(e1));
184 }
185
186
187 extern void
188 st_break(int e1){
189 checkret();
190 // conv->break_();
191 if (control)
192 gen_jmp(blabel);
193 }
194
195
196 extern void
197 st_continue(int e1){
198 checkret();
199 // conv->continue_();
200 if (control) gen_jmp(clabel);
201 }
202
203
204 extern void
205 st_case(int e1){
206 #if CASE_CODE
207 int l,clist=caddr(e1),c;
208 l = fwdlabel();
209 // conv->case_begin_(0,0);
210 // conv->case_(0,0);
211 if (retpending) {
212 ret(); retpending=0;
213 }
214 if (!cslabel) {
215 if (!control) {
216 cmpdimm(car(clist),csvalue1,cslabel=fwdlabel(),1);
217 caddr(clist)=0;
218 } else {
219 error(-1);
220 }
221 }
222 while(clist) {
223 caddr(clist) = l;
224 clist = cadr(c=clist); cadr(c) = 0; // insert destroy cadr of clist
225 cslist=insert_ascend(cslist,c,docase_eq);
226 }
227 fwddef(l);
228 control=1;
229 #else
230 /* casading branch implementation */
231 int c,l;
232 c = caddr(e1);
233 if (retpending) {
234 ret(); retpending=0;
235 }
236 // conv->case_begin_(0,0);
237 // conv->case_(0,0);
238 l=fwdlabel();
239 if (control) {
240 control=0;
241 gen_jmp(l);
242 }
243 if (cslabel) fwddef(cslabel);
244 while(cadr(c)) {
245 cmpdimm(car(c),csvalue1,l,0);
246 c=cadr(c);
247 }
248 cmpdimm(car(c),csvalue1,cslabel=fwdlabel(),1);
249 if (l) fwddef(l);
250 #endif
251 }
252
253
254 extern void
255 st_default(int e1){
256 control=1;
257 checkret();
258 if (dlabel) error(STERR); // double default:
259 dlabel = backdef();
260 // conv->case_(0,1);
261 }
262
263
264 extern void
265 st_return(int e1){
266 int e;
267
268 if (!cslabel) gen_jmp(cslabel = fwdlabel());
269 if(!(e=caddr(e1))) {
270 // conv->return_();
271 // conv->return_end_();
272 retpending = 1;
273 return;
274 }
275 // conv->return_();
276 if (struct_return) {
277 if ((car(type)==STRUCT || car(type)==UNION)&&
278 size(type)==cadr(struct_return)) {
279 if(car(e)==RSTRUCT && car(cadr(e))==FUNCTION) {
280 /* pass the return pointer to the called function */
281 replace_return_struct(cadr(e),
282 rvalue_t(car(struct_return),caddr(struct_return)));
283 replace_return_struct(cadr(e),
284 rvalue_t(car(struct_return),caddr(struct_return)));
285 gexpr(cadr(e),0);
286 } else {
287 type = caddr(struct_return);
288 // e1 = rvalue_t(cadr(struct_return),INT); /* size */
289 e1 = cadr(struct_return); /* size */
290 gexpr(list4(STASS,rvalue(car(struct_return)),e,e1),0);
291 }
292 } else {
293 error(TYERR); /* should check compatible */
294 }
295 } else {
296 gexpr(correct_type(e,cadr(fnptr->ty)),1);
297 }
298 // conv->return_end_();
299 retpending = 1;
300 }
301
302
303 extern void
304 st_goto(int e){
305 NMTBL *nlist,*nptr0;
306 int t,e1,e2,env;
307
308 checkret();
309 // conv->goto_();
310 e1 = caddr(e);
311 if (car(e1)==RINDIRECT) {
312 gen_indirect_goto(cadr(e1));
313 return;
314 } else if (car(e1)==FLABEL) {
315 nlist = (NMTBL *)cadr(e1);
316 nptr0 = name_space_search(nlist,0);
317 t = nptr0->sc;
318 if (t==EMPTY||t==EXTRN1||t==EXTRN) {
319 nptr0 = make_local_scope(nlist,nptr0,0);
320 nptr0->sc = FLABEL;
321 nptr0->dsp = fwdlabel();
322 } else if (!(t==FLABEL||t==BLABEL)) {
323 error(STERR);
324 }
325 gen_jmp(nptr0->dsp);
326 control=0;
327 // conv->sm_();
328 // conv->goto_label_(nptr0);
329 return;
330 } else {
331 /* CbC continuation */
332 // conv->jump_(env);
333 e2 = cadr(e1);
334 env = caddr(e1);
335 if (car(e2) == FNAME) {
336 nptr0=(NMTBL *)cadr(e2);
337 if (nptr0->sc==EMPTY)
338 nptr0->sc = EXTRN1;
339 else if(nptr0->sc==FUNCTION)
340 nptr0->sc = CODE;
341 if (nptr0->ty>0&&car(nptr0->ty)==FUNCTION)
342 car(nptr0->ty)=CODE;
343 }
344 gexpr(list3(CODE,e1,env),0);
345 control=0;
346 // conv->sm_();
347 return;
348 }
349 }
350
351
352 #if ASM_CODE
353 extern void
354 st_asm(int e1){
355 checkret();
356 g_expr_u(list3(ASM,caddr(e1),cadddr(e1)));
357 }
358 #endif
359
360
361 extern void
362 st_label(int e1){
363 NMTBL *nptr,*nlist;
364 nlist = (NMTBL *)caddr(e1);
365 nptr = name_space_search(nlist,0);
366 control=1;
367 checkret();
368 if(nptr->sc == FLABEL) {
369 fwddef(nptr->dsp);
370 } else if(nptr->sc != EMPTY && nptr->sc != EXTRN1 && nptr->sc !=BLABEL) {
371 error(TYERR);
372 } else {
373 nptr->sc=EMPTY;
374 nptr = make_local_scope(nlist,nptr,0);
375 nptr->sc = BLABEL;
376 nptr->dsp = backdef();
377 }
378 // conv->label_();
379 }
380
381 extern void
382 st_comment(int e1){
383 gen_comment((char *)caddr(e1));
384 }
385
386 /*
387 partial evaluator
388 */
389
390 static int convlvar;
391
392 static int
393 pconv_var(int e)
394 {
395 return 0;
396 }
397
398 static int
399 p_lvar(int e1)
400 {
401 return e1;
402 }
403
404 static int
405 pfunction(int e)
406 {
407
408 }
409
410 static int
411 prindirect(int e)
412 {
413
414 }
415
416 static int
417 paddress(int e)
418 {
419
420 }
421
422 static int
423 p_conv(int e)
424 {
425
426 }
427
428 code_lpreinc(int e)
429 {
430
431 }
432
433 static int
434 pbinop(int e)
435 {
436
437 }
438
439 static int
440 pdbinop(int e)
441 {
442
443 }
444
445 static int
446 plbinop(int e)
447 {
448
449 }
450
451 static int
452 psassign(int e)
453 {
454
455 }
456
457 static int
458 passign(int e)
459 {
460
461 }
462
463 static int
464 passop(int e)
465 {
466
467 }
468
469 static int
470 pdassign(int e)
471 {
472
473 }
474
475 static int
476 pdassop(int e)
477 {
478
479 }
480
481 static int
482 plassign(int e)
483 {
484
485 }
486
487 static int
488 plassop(int e)
489 {
490
491 }
492
493 static int
494 palloc(int e)
495 {
496
497 }
498
499 static int
500 pcomma(int e)
501 {
502
503 }
504
505 static int
506 prbit_field(int e)
507 {
508
509 }
510
511 static int
512 pbassign(int e)
513 {
514
515 }
516
517 static int
518 pbassop(int e)
519 {
520
521 }
522
523 static int
524 p_decl(int e)
525 {
526
527 }
528
529 static int
530 p_if(int e)
531 {
532
533 }
534
535 static int
536 p_do(int e)
537 {
538
539 }
540
541 static int
542 p_while(int e)
543 {
544
545 }
546
547 static int
548 p_for(int e)
549 {
550
551 }
552
553 static int
554 p_switch(int e)
555 {
556
557 }
558
559 static int
560 p_comp(int e)
561 {
562
563 }
564
565 static int
566 p_break(int e)
567 {
568
569 }
570
571 static int
572 p_continue(int e)
573 {
574
575 }
576
577 static int
578 p_case(int e)
579 {
580
581 }
582
583 static int
584 p_default(int e)
585 {
586
587 }
588
589 static int
590 p_return(int e)
591 {
592
593 }
594
595 static int
596 p_goto(int e)
597 {
598
599 }
600
601 static int
602 p_asm(int e)
603 {
604
605 }
606
607 static int
608 p_label(int e)
609 {
610
611 }
612
613 static int
614 p_bool(int e)
615 {
616
617 }
618
619 static int
620 pexpr0(int e1)
621 {
622 int e2,e3;
623 NMTBL *n;
624
625 if (inmode) error(-1);
626 e2 = cadr(e1);
627 switch (car(e1)){
628 case GVAR: case RGVAR: case CRGVAR: case CURGVAR: case SRGVAR:
629 case SURGVAR: case REGISTER:
630 #if FLOAT_CODE
631 case DREGISTER: case FREGISTER:
632 #endif
633 #if LONGLONG_CODE
634 case LREGISTER:
635 #endif
636 case LABEL: case CONST:
637 #if FLOAT_CODE
638 case DCONST: case FCONST:
639 #endif
640 #if LONGLONG_CODE
641 case LCONST:
642 #endif
643 case STRING:
644 case FNAME:
645 case RSTRUCT:
646 return e1;
647 case LVAR:
648 case RLVAR: case CRLVAR: case CURLVAR: case SRLVAR: case SURLVAR:
649 #if FLOAT_CODE
650 case FRLVAR: case FRGVAR: case DRLVAR: case DRGVAR:
651 #endif
652 #if LONGLONG_CODE
653 case LRLVAR: case LRGVAR: case LURLVAR: case LURGVAR:
654 return p_lvar(e1);
655 #endif
656 case FUNCTION:
657 return pfunction(e1);
658 case CODE:
659 return list2(car(e1),pexpr0(e2));
660 case INLINE:
661 return pexpr(e1);
662 case INDIRECT:
663 return prindirect(e1);
664 case RINDIRECT: case URINDIRECT:
665 case CRINDIRECT: case CURINDIRECT:
666 case SRINDIRECT: case SURINDIRECT:
667 #if FLOAT_CODE
668 case FRINDIRECT: case DRINDIRECT:
669 #endif
670 #if LONGLONG_CODE
671 case LRINDIRECT: case LURINDIRECT:
672 #endif
673 return prindirect(e1);
674 case ADDRESS:
675 return paddress(pexpr0(e2));
676 case MINUS:
677 if ((e3 = pexpr0(e2))==e2) return e1;
678 if (car(e3)==CONST) return list2(CONST,-cadr(e3));
679 return list2(car(e1),e3);
680 #if LONGLONG_CODE
681 case LMINUS:
682 if ((e3 = pexpr0(e2))==e2) return e1;
683 if (car(e3)==LCONST) return llist2(LCONST,-lcadr(e3));
684 return list2(car(e1),e3);
685 #endif
686 #if FLOAT_CODE
687 case DMINUS:
688 if ((e3 = pexpr0(e2))==e2) return e1;
689 if (car(e3)==DCONST) return dlist2(DCONST,-dcadr(e3));
690 if (car(e3)==FCONST) return dlist2(FCONST,-dcadr(e3));
691 return list2(car(e1),e3);
692 case FMINUS:
693 if ((e3 = pexpr0(e2))==e2) return e1;
694 if (car(e3)==DCONST) return dlist2(DCONST,-dcadr(e3));
695 if (car(e3)==FCONST) return dlist2(FCONST,-dcadr(e3));
696 return list2(car(e1),e3);
697 #endif
698 case CONV:
699 return p_conv(caddr(e1),pexpr0(e2));
700 case BNOT: /* ~ */
701 if ((e3 = pexpr0(e2))==e2) return e1;
702 if (car(e3)==CONST) return list2(CONST,~cadr(e3));
703 return list2(BNOT,e3);
704 case LNOT: /* ! */
705 if ((e3 = pexpr0(e2))==e2) return e1;
706 if (car(e3)==CONST) return list2(CONST,!cadr(e3));
707 return list2(LNOT,e3);
708 case PREINC:
709 case UPREINC:
710 if ((e3 = pexpr0(e2))==e2) return e1;
711 if (car(e3)==CONST) return list2(CONST,cadr(e3)+1);
712 return list2(car(e1),e3);
713 case POSTINC:
714 case UPOSTINC:
715 if ((e3 = pexpr0(e2))==e2) return e1;
716 if (car(e3)==CONST) return e3;
717 return list2(car(e1),e3);
718 #if FLOAT_CODE
719 case DPREINC: /* ++d */
720 if ((e3 = pexpr0(e2))==e2) return e1;
721 if (car(e3)==FCONST) return dlist2(FCONST,dcadr(e3)+1.0);
722 if (car(e3)==DCONST) return dlist2(DCONST,dcadr(e3)+1.0);
723 return list2(car(e1),e3);
724 case DPOSTINC: /* d++ */
725 if ((e3 = pexpr0(e2))==e2) return e1;
726 if (car(e3)==FCONST||car(e3)==DCONST) return e3;
727 return list2(car(e1),e3);
728 case FPREINC: /* ++f */
729 if ((e3 = pexpr0(e2))==e2) return e1;
730 if (car(e3)==FCONST) return dlist2(FCONST,dcadr(e3)+1.0);
731 if (car(e3)==DCONST) return dlist2(DCONST,dcadr(e3)+1.0);
732 return list2(car(e1),e3);
733 case FPOSTINC: /* f++ */
734 if ((e3 = pexpr0(e2))==e2) return e1;
735 if (car(e3)==FCONST||car(e3)==DCONST) return e3;
736 return list2(car(e1),e3);
737 #endif
738 #if LONGLONG_CODE
739 case LPREINC: /* ++d */
740 case LUPREINC: /* ++d */
741 if ((e3 = pexpr0(e2))==e2) return e1;
742 if (car(e3)==LCONST) return llist2(LCONST,lcadr(e3)+1);
743 return list2(car(e1),e3);
744 case LPOSTINC: /* d++ */
745 case LUPOSTINC: /* d++ */
746 if ((e3 = pexpr0(e2))==e2) return e1;
747 if (car(e3)==LCONST) return e3;
748 return list2(car(e1),e3);
749 code_lpreinc(e1,e2,USE_CREG);
750 return ULONGLONG;
751 #endif
752 case MUL: case UMUL:
753 case DIV: case UDIV:
754 case MOD: case UMOD:
755 case LSHIFT: case ULSHIFT: case RSHIFT: case URSHIFT:
756 case ADD: case SUB: case BAND: case EOR: case BOR: case CMP: case CMPGE:
757 case UCMP: case CMPEQ: case CMPNEQ: case UCMPGE:
758 pbinop(car(e1),pexpr0(cadr(e1)),pexpr0(caddr(e1)));
759 return INT;
760 #if FLOAT_CODE
761 case DMUL: case DDIV:
762 case DADD: case DSUB:
763 case DCMP: case DCMPGE: case DCMPEQ: case DCMPNEQ:
764 return pdbinop(car(e1),pexpr0(cadr(e1)),pexpr0(caddr(e1)),1);
765 case FMUL: case FDIV:
766 case FADD: case FSUB:
767 case FCMP: case FCMPGE: case FCMPEQ: case FCMPNEQ:
768 return pdbinop(car(e1),pexpr0(cadr(e1)),pexpr0(caddr(e1)),0);
769 #endif
770 #if LONGLONG_CODE
771 case LMUL: case LUMUL:
772 case LDIV: case LUDIV:
773 case LMOD: case LUMOD:
774 case LLSHIFT: case LULSHIFT: case LRSHIFT: case LURSHIFT:
775 case LADD: case LSUB: case LBAND: case LEOR: case LBOR: case LCMP:
776 return plbinop(car(e1),pexpr0(cadr(e1)),pexpr0(caddr(e1)));
777 #endif
778 case LCOND: case DCOND: case FCOND: case COND:
779 e3 = pexpr0(e2);
780 if (car(e3)==CONST) return pexpr0(cadr(e3)?caddr(e1):cadddr(e1));
781 return list4(car(e1),e3,pexpr0(cadr(e1)),pexpr0(cadr(e2)));
782 case STASS:
783 return psassign(e1);
784 case ASS: case CASS: case SASS:
785 return passign(e1);
786 case SASSOP: case SUASSOP:
787 case ASSOP: case CASSOP: case CUASSOP:
788 return passop(e1);
789 #if FLOAT_CODE
790 case FASS: case DASS:
791 return pdassign(e1);
792 case DASSOP: case FASSOP:
793 return pdassop(e1);
794 #endif
795 #if LONGLONG_CODE
796 case LASS:
797 return plassign(e1);
798 case LASSOP: case LUASSOP:
799 return plassop(e1);
800 #endif
801 case ALLOCA:
802 return palloc(pexpr0(e2));
803 case BUILTINP:
804 return list2(CONST,is_const(pexpr0(e2)));
805 case COMMA:
806 return pcomma(pexpr0(e2),pexpr0(caddr(e1)));
807 case RETURN:
808 case ENVIRONMENT:
809 case LCALL:
810 return e1;
811 #if BIT_FIELD_CODE
812 case RBIT_FIELD:
813 return prbit_field(e1);
814 case BASS:
815 return pbassign(e1);
816 case BPREINC:
817 case BPOSTINC:
818 case BASSOP:
819 return pbassop(e1);
820 #endif
821 #if ASM_CODE
822 case ASM:
823 return list3(ASM,list4(
824 pexpr0(car(e2)),pexpr0(cadr(e2)),pexpr0(caddr(e2)),pexpr0(cadddr(e2))),
825 pexpr0(caddr(e1)));
826 #endif
827 case ST_DECL: return p_decl(e1);
828 case ST_IF: return p_if(e1);
829 case ST_DO: return p_do(e1);
830 case ST_WHILE: return p_while(e1);
831 case ST_FOR: return p_for(e1);
832 case ST_SWITCH: return p_switch(e1);
833 case ST_COMP: return p_comp(e1);
834 case ST_BREAK: return p_break(e1);
835 case ST_CONTINUE: return p_continue(e1);
836 case ST_CASE: return p_case(e1);
837 case ST_DEFAULT: return p_default(e1);
838 case ST_RETURN: return p_return(e1);
839 case ST_GOTO: return p_goto(e1);
840 case ST_ASM: return p_asm(e1);
841 case ST_LABEL: return p_label(e1);
842 case ST_COMMENT: return p_comment(e1);
843 default:
844 return p_bool(e1);
845 }
846 return VOID;
847 }
848
849 int
850 pexpr(int e)
851 {
852 int sconvlvar = convlvar;
853 // compute new disp, and local variable table
854 convlvar = pconv_var(e);
855 e = pexpr0(e1);
856 convlvar = sconvlvar;
857 return e;
858 }
859
860 /* end */