Mercurial > hg > CbC > old > device
comparison mc-nop-386.c @ 2:b3f259ac34a1
args
author | kono |
---|---|
date | Thu, 13 Jan 2000 06:27:07 +0900 |
parents | 0529f5abe9d0 |
children | ca8e268dd7d4 |
comparison
equal
deleted
inserted
replaced
1:0529f5abe9d0 | 2:b3f259ac34a1 |
---|---|
61 int cadddr(int e); | 61 int cadddr(int e); |
62 int backdef(void); | 62 int backdef(void); |
63 int error(int n); | 63 int error(int n); |
64 int size(int t); | 64 int size(int t); |
65 int list3(int e1, int e2, int e3); | 65 int list3(int e1, int e2, int e3); |
66 extern int scalar(int); | |
67 extern int reverse0(int); | |
66 | 68 |
67 #define TEXT_EMIT_MODE 0 | 69 #define TEXT_EMIT_MODE 0 |
68 #define DATA_EMIT_MODE 1 | 70 #define DATA_EMIT_MODE 1 |
69 #define RODATA_EMIT_MODE 2 | 71 #define RODATA_EMIT_MODE 2 |
70 | 72 |
759 printf("\tcall\t*%s\n",crn); | 761 printf("\tcall\t*%s\n",crn); |
760 } | 762 } |
761 if (nargs) printf("\taddl $%d,%%esp\n",4*nargs); | 763 if (nargs) printf("\taddl $%d,%%esp\n",4*nargs); |
762 } | 764 } |
763 | 765 |
766 int | |
767 arg_size(int e3) | |
768 { | |
769 int i,nargs,offset_list,e,t; | |
770 | |
771 offset_list = 0; | |
772 /* we should use prototypes's type */ | |
773 for (i = nargs = 0; e3;e3 =cadr(e3)) { | |
774 e = car(e3); t = caddr(e3); | |
775 if (i++ < MAX_REGISTER_VAR && scalar(t)) { | |
776 offset_list = list3(REG_ESI+i,offset_list,e); | |
777 } else { | |
778 nargs += (car(e3)==CHAR?int_size:size(t)); | |
779 offset_list = | |
780 list3(-nargs+disp_offset+int_size,offset_list,e); | |
781 } | |
782 } | |
783 return offset_list; | |
784 } | |
785 | |
764 void | 786 void |
765 jump(int e1, int env) | 787 jump(int e1, int env) |
766 { | 788 { |
767 int i,e2,e3,e4,e5,nargs,regs; | 789 int i,args,e2,e3,e4,e5,nargs,nargs0,regs; |
768 NMTBL *n,*code0; | 790 NMTBL *n,*code0; |
769 int new_disp; | 791 int new_disp; |
770 char *xrn; | 792 char *xrn; |
771 | 793 |
794 /* We need three passes. Compute Stack size, Compute Arg, Copy it. */ | |
772 /* count number of args */ | 795 /* count number of args */ |
773 nargs = 0; | 796 args = caddr(e1); |
774 for (e3 = caddr(e1); e3;e3 =cadr(e3)) nargs++; | 797 reverse0(args); |
775 new_disp = -(nargs-MAX_REGISTER_VAR)*int_size; | 798 nargs = arg_size(args); |
776 if (new_disp > 0) | 799 new_disp = car(nargs); |
777 new_disp=0; | |
778 /* printf("# new_disp %d,disp %d\n",new_disp,disp); */ | |
779 if (new_disp < disp) { | 800 if (new_disp < disp) { |
780 printf("\tlea %d(%%ebp),%%esp\n",new_disp+disp_offset); | 801 printf("\tlea %d(%%ebp),%%esp\n",new_disp+disp_offset); |
781 } | 802 } |
782 /* compute jump address */ | 803 /* compute jump address */ |
783 e2 = cadr(e1); | 804 e2 = cadr(e1); |
788 } | 809 } |
789 } else { /* indirect */ | 810 } else { /* indirect */ |
790 g_expr(e2); | 811 g_expr(e2); |
791 emit_push(); | 812 emit_push(); |
792 } | 813 } |
793 /* compute arguments */ | 814 /* compute arguments in reverse order */ |
794 regs = nargs-1; | 815 regs = 0; |
795 i=0; | 816 nargs; |
796 for (e3 = caddr(e1); e3;e3 =cadr(e3),i++) { | 817 for (e3=nargs; e3;e3 =cadr(e3)) { |
797 n=(NMTBL *)(e5=(cadr(e4 = car(e3)))); | 818 n=(NMTBL *)(e5=(cadr(e4 = caddr(e3)))); |
798 switch(car(e4)) { | 819 switch(car(e4)) { |
799 case FNAME: | 820 case FNAME: |
800 printf("\tlea %s,%s\n",n->nm,crn); | 821 printf("\tlea %s,%s\n",n->nm,crn); |
801 emit_push(); | 822 emit_push(); |
802 break; | 823 break; |
803 case ADDRESS: | 824 case ADDRESS: |
804 g_expr(e5); | 825 g_expr(e5); |
805 emit_push(); | 826 emit_push(); |
806 break; | 827 break; |
807 /* | |
808 printf("# cadr(e4) %d ==disp_offset+(-1-i)*int_size %d\n", cadr(e4), disp_offset+(-2-i)*int_size); | |
809 */ | |
810 case RLVAR: | 828 case RLVAR: |
811 case CRLVAR: | 829 case CRLVAR: |
812 if (env==0 && cadr(e4)==disp_offset+(-1-i)*int_size) { | 830 if (env==0) { |
813 /* Same positioned local variable. No need to copy */ | 831 if (e5<0 && e5+disp_offset==nargs) { |
814 reg_stack[reg_sp++] = -2; | 832 /* The same positioned local variable. No need to copy */ |
815 --regs; | 833 reg_stack[reg_sp++] = -2; |
816 continue; | 834 } |
817 } | 835 } |
818 case REGISTER: | 836 case REGISTER: |
819 if (rname[cadr(e4)]==REG_ESI+regs) { | 837 if (rname[e5]==REG_ESI+regs) { |
820 /* Same register variable. No need to copy */ | 838 /* Same register variable. No need to copy */ |
821 reg_stack[reg_sp++] = cadr(e4); | 839 reg_stack[reg_sp++] = e5; |
822 --regs; | |
823 continue; | |
824 } | 840 } |
841 break; | |
825 default: | 842 default: |
826 g_expr(e4); | 843 g_expr(e4); |
827 emit_push(); | 844 emit_push(); |
828 } | 845 } |
829 --regs; | 846 regs++; |
830 } | 847 } |
831 /* save frame pointer before jump in fuction */ | |
832 if (fnptr->sc==FUNCTION) { | |
833 printf("\tmovl %%ebp,%d(%%ebp)\n",disp_offset); | |
834 } | |
835 if (env) { | 848 if (env) { |
836 /* change frame pointer */ | 849 /* change the frame pointer */ |
837 g_expr(env); | 850 g_expr(env); |
838 printf("\tmovl %s,%%ebp\n",crn); | 851 printf("\tmovl %s,%%ebp\n",crn); |
839 } | 852 } |
840 /* copy arguments to destination environment if necessary */ | 853 /* copy arguments to destination environment if necessary */ |
841 for(i=0;i<nargs;i++) { | 854 reverse0(args); |
842 if (i>=MAX_REGISTGER_VAR) { | 855 for (e3=args; e3;e3 =cadr(e3)) { |
856 if ((e4=car(e3))>0) { | |
857 /* register case */ | |
858 if (reg_stack[--reg_sp]>=REG_ESI) { | |
859 /* the same registger */ | |
860 } else { | |
861 if(reg_stack[reg_sp]<0) { | |
862 printf("\tpopl %s\n",reg_name[rname[e4]]); | |
863 } else { | |
864 printf("\tmovl %s,%s\n", | |
865 reg_name[rname[reg_stack[reg_sp]]], | |
866 reg_name[rname[e4]]); | |
867 free_register(reg_stack[reg_sp]); | |
868 } | |
869 } | |
870 } else { | |
871 /* local variable case */ | |
843 if (reg_stack[reg_sp-1]== -2) { | 872 if (reg_stack[reg_sp-1]== -2) { |
844 /* same positioned variable */ | 873 /* same positioned variable */ |
845 reg_sp--; | 874 reg_sp--; |
846 } else { | 875 } else { |
847 xrn=emit_pop(0); | 876 xrn=emit_pop(0); |
848 printf("\tmovl %s,%d(%%ebp)\n",xrn, | 877 printf("\tmovl %s,%d(%%ebp)\n",xrn, e4); |
849 disp_offset+(-(nargs-i))*int_size); | |
850 } | |
851 } else if (reg_stack[--reg_sp]>=REG_ESI) { | |
852 /* the same registger */ | |
853 ; | |
854 } else { | |
855 if(reg_stack[reg_sp]<0) { | |
856 printf("\tpopl %s\n",reg_name[rname[REG_ESI+i]]); | |
857 } else { | |
858 printf("\tmovl %s,%s\n", | |
859 reg_name[rname[reg_stack[reg_sp]]], | |
860 reg_name[rname[REG_ESI+i]]); | |
861 free_register(reg_stack[reg_sp]); | |
862 } | 878 } |
863 } | 879 } |
864 } | 880 } |
865 if (car(e2) != FNAME) { | 881 if (car(e2) != FNAME) { |
866 xrn=emit_pop(0); | 882 xrn=emit_pop(0); |
867 } | 883 } |
868 /* printf("# new_disp %d,disp %d\n",new_disp,disp); */ | 884 if (fnptr->sc==FUNCTION) { |
885 printf("\tlea %d(%%ebp),%%ebp\n",disp_offset+int_size); | |
886 } | |
869 if (new_disp>disp) { | 887 if (new_disp>disp) { |
870 /* shrink stack if necessary */ | 888 /* shrink stack if necessary */ |
871 printf("\tlea %d(%%ebp),%%esp\n",new_disp+disp_offset); | 889 printf("\tlea %d(%%ebp),%%esp\n",new_disp); |
872 } | |
873 if (fnptr->sc==FUNCTION) { | |
874 /* link operation for leave, %ebp must point saved old %ebp */ | |
875 printf("\tlea %d(%%ebp),%%ebp\n",disp_offset); | |
876 } | 890 } |
877 if (car(e2) == FNAME) { | 891 if (car(e2) == FNAME) { |
878 printf("\tjmp %s\n",code0->nm); | 892 printf("\tjmp %s\n",code0->nm); |
879 } else { | 893 } else { |
880 printf("\tjmp *%s\n",xrn); | 894 printf("\tjmp *%s\n",xrn); |
1262 | 1276 |
1263 void | 1277 void |
1264 code_enter(char *name) | 1278 code_enter(char *name) |
1265 { | 1279 { |
1266 disp_offset = code_disp_offset; | 1280 disp_offset = code_disp_offset; |
1267 emit_init(); | |
1268 printf("\t.align 4\n"); | 1281 printf("\t.align 4\n"); |
1269 if (stmode!=STATIC) | 1282 if (stmode!=STATIC) |
1270 printf(".globl %s\n",name); | 1283 printf(".globl %s\n",name); |
1271 printf("\t.type\t%s,@function\n",name); | 1284 printf("\t.type\t%s,@function\n",name); |
1272 printf("%s:\n",name); | 1285 printf("%s:\n",name); |
1291 | 1304 |
1292 void | 1305 void |
1293 enter(char *name) | 1306 enter(char *name) |
1294 { | 1307 { |
1295 disp_offset = func_disp_offset; | 1308 disp_offset = func_disp_offset; |
1296 emit_init(); | |
1297 printf("\t.align 2\n"); | 1309 printf("\t.align 2\n"); |
1298 if (stmode!=STATIC) | 1310 if (stmode!=STATIC) |
1299 printf(".globl %s\n",name); | 1311 printf(".globl %s\n",name); |
1300 printf("%s:\n",name); | 1312 printf("%s:\n",name); |
1301 printf("\t.type\t%s,@function\n",name); | 1313 printf("\t.type\t%s,@function\n",name); |