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)