Mercurial > hg > CbC > old > device
comparison mc-nop-386.c @ 47:f6b5e4f1a962
*** empty log message ***
author | kono |
---|---|
date | Sat, 15 Feb 2003 18:19:27 +0900 |
parents | b1c8ac8c308d |
children | 8575ec496cd4 |
comparison
equal
deleted
inserted
replaced
46:b1c8ac8c308d | 47:f6b5e4f1a962 |
---|---|
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,int reg); | 55 static void tosop(int op,int reg); |
56 static void edx_cleanup(); | 56 static void edx_cleanup(); |
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(int from,int to,int length,int offset); | 58 static void emit_copy(int from,int to,int length,int offset,int value); |
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); |
838 } | 838 } |
839 | 839 |
840 #define MAX_COPY_LEN 20 | 840 #define MAX_COPY_LEN 20 |
841 | 841 |
842 void | 842 void |
843 emit_copy(int from,int to,int length,int offset) | 843 emit_copy(int from,int to,int length,int offset,int value) |
844 { | 844 { |
845 int fix = 0; | 845 int fix = 0; |
846 if (length<=0) return; | 846 if (length<=0) return; |
847 switch (length) { | 847 switch (length) { |
848 case 0: break; | 848 case 0: break; |
859 printf("\tmovl %s,%d(%s)\n",register_name(dreg,0), offset,register_name(to,0)); | 859 printf("\tmovl %s,%d(%s)\n",register_name(dreg,0), offset,register_name(to,0)); |
860 break; | 860 break; |
861 default: | 861 default: |
862 if (length <=MAX_COPY_LEN) { | 862 if (length <=MAX_COPY_LEN) { |
863 for(;length>=4;length-=4,offset+=4) | 863 for(;length>=4;length-=4,offset+=4) |
864 emit_copy(from,to,4,offset); | 864 emit_copy(from,to,4,offset,0); |
865 for(;length>=2;length-=2,offset+=2) | 865 for(;length>=2;length-=2,offset+=2) |
866 emit_copy(from,to,2,offset); | 866 emit_copy(from,to,2,offset,0); |
867 if(length>0) | 867 if(length>0) |
868 emit_copy(from,to,length,offset); | 868 emit_copy(from,to,length,offset,0); |
869 break; | 869 break; |
870 } | 870 } |
871 use_register(from,REG_ESI,1); | 871 use_register(from,REG_ESI,1); |
872 use_register(to, REG_EDI,1); | 872 use_register(to, REG_EDI,1); |
873 use_register(dreg,REG_ECX,0); | 873 use_register(dreg,REG_ECX,0); |
874 printf("\tmovl $%d,%%ecx\n",length/4); | 874 printf("\tmovl $%d,%%ecx\n",length/4); |
875 fix = (length/4)*4; | 875 fix = (length/4)*4; |
876 printf("\tcld\n\trep\n\tmovsl\n"); | 876 printf("\tcld\n\trep\n\tmovsl\n"); |
877 if(length%4) { | 877 if(length%4) { |
878 emit_copy(from,to,length,offset+length/4); | 878 emit_copy(from,to,length,offset+length/4,0); |
879 } | 879 } |
880 } | 880 } |
881 if (value) { | |
881 /* this code is necessary for the value of assignment or function call */ | 882 /* this code is necessary for the value of assignment or function call */ |
882 /* otherwise we don't need this */ | 883 /* otherwise we don't need this */ |
883 if (fix) printf("\tsubl $%d,%s\n",fix,register_name(to,0)); | 884 if (fix) printf("\tsubl $%d,%s\n",fix,register_name(to,0)); |
884 if(creg!=to) { | 885 if(creg!=to) { |
885 if (to==dreg) | 886 if (to==dreg) |
886 printf("\tmovl %s,%s\n",register_name(to,0),register_name(creg,0)); | 887 printf("\tmovl %s,%s\n",register_name(to,0),register_name(creg,0)); |
887 else { | 888 else { |
888 free_register(creg); creg=to; | 889 free_register(creg); creg=to; |
890 } | |
889 } | 891 } |
890 } | 892 } |
891 regv[from]=regv[to]=regv[dreg]=0; | 893 regv[from]=regv[to]=regv[dreg]=0; |
892 regv[creg]=1; | 894 regv[creg]=1; |
893 } | 895 } |
923 if (save) | 925 if (save) |
924 printf("\tlea %d(%%esp),%s\n",size_of_int,register_name(xreg,0)); | 926 printf("\tlea %d(%%esp),%s\n",size_of_int,register_name(xreg,0)); |
925 else | 927 else |
926 printf("\tmovl %%esp,%s\n",register_name(xreg,0)); | 928 printf("\tmovl %%esp,%s\n",register_name(xreg,0)); |
927 regv[xreg]=1; | 929 regv[xreg]=1; |
928 emit_copy(creg,xreg,length,0); | 930 emit_copy(creg,xreg,length,0,0); |
929 /* we have value in creg, it may be changed */ | 931 /* we have value in creg, it may be changed */ |
930 if (save) { | 932 if (save) { |
931 if(creg==xreg) { | 933 if(creg==xreg) { |
932 creg = get_register(); /* creg is freed in emit_copy */ | 934 creg = get_register(); /* creg is freed in emit_copy */ |
933 printf("\tmovl %s,%s\n",register_name(xreg,0),register_name(creg,0)); | |
934 regv[creg]=1; | |
935 } | 935 } |
936 printf("\tpopl %s\n",register_name(xreg,0)); | 936 printf("\tpopl %s\n",register_name(xreg,0)); |
937 regv[xreg]=1; | 937 regv[xreg]=1; |
938 } else | 938 } else |
939 free_register(xreg); | 939 free_register(xreg); |
1253 sz = cadddr(e1); /* size of struct or union */ | 1253 sz = cadddr(e1); /* size of struct or union */ |
1254 g_expr(e4); | 1254 g_expr(e4); |
1255 emit_push(); | 1255 emit_push(); |
1256 g_expr(e2); | 1256 g_expr(e2); |
1257 xreg = emit_pop(0); | 1257 xreg = emit_pop(0); |
1258 emit_copy(xreg,creg,sz,0); | 1258 emit_copy(xreg,creg,sz,0,1); |
1259 emit_pop_free(xreg); | 1259 emit_pop_free(xreg); |
1260 return; | 1260 return; |
1261 } | 1261 } |
1262 | 1262 |
1263 void | 1263 void |