Mercurial > hg > CbC > old > device
comparison mc-nop-386.c @ 38:d48d952da354
struct copy continue
author | kono |
---|---|
date | Tue, 11 Feb 2003 11:26:51 +0900 |
parents | 412ad2e6c2a2 |
children | c63c4fdeb9a7 |
comparison
equal
deleted
inserted
replaced
37:412ad2e6c2a2 | 38:d48d952da354 |
---|---|
53 /* static void st_indexx(int byte, int n, int xreg); */ | 53 /* static void st_indexx(int byte, int n, int xreg); */ |
54 static void string(int e1); | 54 static void string(int e1); |
55 static void tosop(int op); | 55 static void tosop(int op); |
56 static void div_cleanup(char *orn); | 56 static void div_cleanup(char *orn); |
57 static void use_register(int virt, int real, int move); | 57 static void use_register(int virt, int real, int move); |
58 static void emit_copy(char *from,char *to,int length,int offset); | 58 static void emit_copy(int from,int to,int length,int offset); |
59 | 59 |
60 extern int error(int n); | 60 extern int error(int n); |
61 extern int fwdlabel(void); | 61 extern int fwdlabel(void); |
62 extern void fwddef(int l); | 62 extern void fwddef(int l); |
63 extern int backdef(void); | 63 extern int backdef(void); |
175 } | 175 } |
176 | 176 |
177 char * | 177 char * |
178 register_name(int i,int byte) | 178 register_name(int i,int byte) |
179 { | 179 { |
180 if (i<0) { | |
181 error(REG_ERR); | |
182 return "%eax"; | |
183 } | |
180 if (byte && rname[i] <= REG_EDX) { | 184 if (byte && rname[i] <= REG_EDX) { |
181 return reg_name_l[rname[i]]; | 185 return reg_name_l[rname[i]]; |
182 } else { | 186 } else { |
183 return reg_name[rname[i]]; /* should be error */ | 187 return reg_name[rname[i]]; /* should be error */ |
184 } | 188 } |
738 } | 742 } |
739 | 743 |
740 #define MAX_COPY_LEN 20 | 744 #define MAX_COPY_LEN 20 |
741 | 745 |
742 void | 746 void |
743 emit_copy(char *from,char *to,int length,int offset) | 747 emit_copy(int from,int to,int length,int offset) |
744 { | 748 { |
745 if (length<0) return; | 749 if (length<0) return; |
746 switch (length) { | 750 switch (length) { |
747 case 0: break; | 751 case 0: break; |
748 case 1: | 752 case 1: |
749 printf("\tmovb %d(%s),%s\n",offset,from, reg_name_l[rname[dreg]] ); | 753 printf("\tmovb %d(%s),%s\n",offset,register_name(from,0), reg_name_l[rname[dreg]] ); |
750 printf("\tmovb %s,%d(%s)\n",reg_name_l[rname[dreg]] ,offset,to); | 754 printf("\tmovb %s,%d(%s)\n",reg_name_l[rname[dreg]] ,offset,register_name(to,0)); |
751 break; | 755 break; |
752 case 2: | 756 case 2: |
753 printf("\tmovw %d(%s),%s\n",offset,from, reg_name_w[rname[dreg]] ); | 757 printf("\tmovw %d(%s),%s\n",offset,register_name(from,0), reg_name_w[rname[dreg]] ); |
754 printf("\tmovw %s,%d(%s)\n",reg_name_w[rname[dreg]] ,offset,to); | 758 printf("\tmovw %s,%d(%s)\n",reg_name_w[rname[dreg]] ,offset,register_name(to,0)); |
755 break; | 759 break; |
756 case 4: | 760 case 4: |
757 printf("\tmovl %d(%s),%s\n",offset,from, register_name(dreg,0)); | 761 printf("\tmovl %d(%s),%s\n",offset,register_name(from,0), register_name(dreg,0)); |
758 printf("\tmovl %s,%d(%s)\n",register_name(dreg,0), offset,to); | 762 printf("\tmovl %s,%d(%s)\n",register_name(dreg,0), offset,register_name(to,0)); |
759 break; | 763 break; |
760 default: | 764 default: |
761 if (length <=MAX_COPY_LEN) { | 765 if (length <=MAX_COPY_LEN) { |
762 for(;length>=4;length-=4,offset+=4) | 766 for(;length>=4;length-=4,offset+=4) |
763 emit_copy(from,to,4,offset); | 767 emit_copy(from,to,4,offset); |
765 emit_copy(from,to,2,offset); | 769 emit_copy(from,to,2,offset); |
766 if(length>0) | 770 if(length>0) |
767 emit_copy(from,to,length,offset); | 771 emit_copy(from,to,length,offset); |
768 return; | 772 return; |
769 } | 773 } |
770 printf("\txchg %%edi,%s\n",from); | 774 use_register(from,REG_EDI,1); |
771 printf("\txchg %%esi,%s\n",to); | 775 use_register(to, REG_ESI,1); |
772 printf("\txchg %%ecx,%s\n",register_name(dreg,0)); | 776 use_register(dreg,REG_ECX,1); |
773 printf("\tmovl $%d,%%ecx\n",length/4); | 777 printf("\tmovl $%d,%%ecx\n",length/4); |
774 printf("\tcld\n\trep\n\tmovsl\n"); | 778 printf("\tcld\n\trep\n\tmovsl\n"); |
775 printf("\txchg %%ecx,%s\n",register_name(dreg,0)); | |
776 printf("\txchg %%esi,%s\n",to); | |
777 printf("\txchg %%edi,%s\n",from); | |
778 if(length%4) { | 779 if(length%4) { |
779 emit_copy("%esi","%edi",length,offset+length/4); | 780 emit_copy(from,to,length,offset+length/4); |
780 } | 781 } |
781 } | 782 } |
782 } | 783 } |
783 | 784 |
784 int | 785 int |
785 struct_push(int e4,int t) | 786 struct_push(int e4,int t) |
786 { | 787 { |
787 int length; | 788 int length,xreg,save; |
788 g_expr(e4); | 789 g_expr(e4); |
789 length=size(t); | 790 length=size(t); |
790 if(length%size_of_int) { | 791 if(length%size_of_int) { |
791 length += size_of_int - (length%size_of_int); | 792 length += size_of_int - (length%size_of_int); |
792 } | 793 } |
794 /* I think, after g_expr, at least two registers are free */ | |
793 printf("\tsubl $%d,%%esp\n",length); | 795 printf("\tsubl $%d,%%esp\n",length); |
794 if (length<=MAX_COPY_LEN) | 796 if (register_full()) { |
795 emit_copy(register_name(creg,0),"%esp",length,0); | 797 /* this is wrong assumption */ |
796 else { | 798 save = 1; |
797 printf("\tpushl %%edi\n"); | 799 printf("\tpushl %s\n",register_name(lreg,0)); |
798 printf("\tpushl %%esi\n"); | 800 xreg = lreg; |
799 printf("\tpushl %%ecx\n"); | 801 } else { |
800 printf("\tleal 12(%%esp),%%edi\n"); | 802 save=0; |
801 if (rname[creg]!=REG_ESI) | 803 xreg = get_register(); |
802 printf("\tmovl %s,%%esi\n",register_name(creg,0)); | 804 } |
803 printf("\tmovl $%d,%%ecx\n",length/size_of_int); | 805 printf("\tmovl %%esp,%s\n",register_name(xreg,0)); |
804 printf("\tcld\n\trep\n\tmovsl\n"); | 806 emit_copy(creg,xreg,length,0); |
805 printf("\tpopl %%ecx\n"); | 807 if (save) { |
806 printf("\tpopl %%esi\n"); | 808 printf("\tpopl %s\n",register_name(lreg,0)); |
807 printf("\tpopl %%edi\n"); | 809 } else |
808 } | 810 free_register(xreg); |
809 return length/size_of_int; | 811 return length/size_of_int; |
810 } | 812 } |
811 | 813 |
812 void | 814 void |
813 function(int e1) | 815 function(int e1) |
1105 } | 1107 } |
1106 | 1108 |
1107 void | 1109 void |
1108 sassign(int e1) | 1110 sassign(int e1) |
1109 { | 1111 { |
1110 int e2,e3,e4,sz; | 1112 int e2,e3,e4,sz,xreg; |
1111 char *xrn; | |
1112 | 1113 |
1113 /* structure assignment */ | 1114 /* structure assignment */ |
1114 e2 = cadr(e1); /* pointer variable to the struct */ | 1115 e2 = cadr(e1); /* pointer variable to the struct */ |
1115 e3 = cadr(e2); /* offset of the variable (distination) */ | 1116 e3 = cadr(e2); /* offset of the variable (distination) */ |
1116 e4 = caddr(e1); /* rright value (source) */ | 1117 e4 = caddr(e1); /* rright value (source) */ |
1117 sz = cadddr(e1); /* size of struct or union */ | 1118 sz = cadddr(e1); /* size of struct or union */ |
1118 g_expr(e4); | 1119 g_expr(e4); |
1119 emit_push(); | 1120 emit_push(); |
1120 g_expr(e2); | 1121 g_expr(e2); |
1121 xrn = register_name(emit_pop(0),0); | 1122 xreg = emit_pop(0); |
1122 emit_copy(xrn,register_name(creg,0),sz,0); | 1123 emit_copy(xreg,creg,sz,0); |
1123 return; | 1124 return; |
1124 } | 1125 } |
1125 | 1126 |
1126 void | 1127 void |
1127 assign(int e1) | 1128 assign(int e1) |