Commit 24f9e90b0e183d501ff77c6851cbe11e7d7254a1
1 parent
a4a0ffdb
16bit/override support in string operations
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@54 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
273 additions
and
229 deletions
op_string.h
0 → 100644
1 | + | |
2 | +void OPPROTO glue(glue(op_movs, SUFFIX), STRING_SUFFIX)(void) | |
3 | +{ | |
4 | + int v, inc; | |
5 | + inc = (DF << SHIFT); | |
6 | + v = glue(ldu, SUFFIX)(SI_ADDR); | |
7 | + glue(st, SUFFIX)(DI_ADDR, v); | |
8 | + inc = (DF << SHIFT); | |
9 | + INC_SI(); | |
10 | + INC_DI(); | |
11 | +} | |
12 | + | |
13 | +void OPPROTO glue(glue(op_rep_movs, SUFFIX), STRING_SUFFIX)(void) | |
14 | +{ | |
15 | + int v, inc; | |
16 | + inc = (DF << SHIFT); | |
17 | + while (CX != 0) { | |
18 | + v = glue(ldu, SUFFIX)(SI_ADDR); | |
19 | + glue(st, SUFFIX)(DI_ADDR, v); | |
20 | + INC_SI(); | |
21 | + INC_DI(); | |
22 | + DEC_CX(); | |
23 | + } | |
24 | + FORCE_RET(); | |
25 | +} | |
26 | + | |
27 | +void OPPROTO glue(glue(op_stos, SUFFIX), STRING_SUFFIX)(void) | |
28 | +{ | |
29 | + int inc; | |
30 | + glue(st, SUFFIX)(DI_ADDR, EAX); | |
31 | + inc = (DF << SHIFT); | |
32 | + INC_DI(); | |
33 | +} | |
34 | + | |
35 | +void OPPROTO glue(glue(op_rep_stos, SUFFIX), STRING_SUFFIX)(void) | |
36 | +{ | |
37 | + int inc; | |
38 | + inc = (DF << SHIFT); | |
39 | + while (CX != 0) { | |
40 | + glue(st, SUFFIX)(DI_ADDR, EAX); | |
41 | + INC_DI(); | |
42 | + DEC_CX(); | |
43 | + } | |
44 | + FORCE_RET(); | |
45 | +} | |
46 | + | |
47 | +void OPPROTO glue(glue(op_lods, SUFFIX), STRING_SUFFIX)(void) | |
48 | +{ | |
49 | + int v, inc; | |
50 | + v = glue(ldu, SUFFIX)(SI_ADDR); | |
51 | +#if SHIFT == 0 | |
52 | + EAX = (EAX & ~0xff) | v; | |
53 | +#elif SHIFT == 1 | |
54 | + EAX = (EAX & ~0xffff) | v; | |
55 | +#else | |
56 | + EAX = v; | |
57 | +#endif | |
58 | + inc = (DF << SHIFT); | |
59 | + INC_SI(); | |
60 | +} | |
61 | + | |
62 | +/* don't know if it is used */ | |
63 | +void OPPROTO glue(glue(op_rep_lods, SUFFIX), STRING_SUFFIX)(void) | |
64 | +{ | |
65 | + int v, inc; | |
66 | + inc = (DF << SHIFT); | |
67 | + while (CX != 0) { | |
68 | + v = glue(ldu, SUFFIX)(SI_ADDR); | |
69 | +#if SHIFT == 0 | |
70 | + EAX = (EAX & ~0xff) | v; | |
71 | +#elif SHIFT == 1 | |
72 | + EAX = (EAX & ~0xffff) | v; | |
73 | +#else | |
74 | + EAX = v; | |
75 | +#endif | |
76 | + INC_SI(); | |
77 | + DEC_CX(); | |
78 | + } | |
79 | + FORCE_RET(); | |
80 | +} | |
81 | + | |
82 | +void OPPROTO glue(glue(op_scas, SUFFIX), STRING_SUFFIX)(void) | |
83 | +{ | |
84 | + int v, inc; | |
85 | + | |
86 | + v = glue(ldu, SUFFIX)(DI_ADDR); | |
87 | + inc = (DF << SHIFT); | |
88 | + INC_DI(); | |
89 | + CC_SRC = EAX; | |
90 | + CC_DST = EAX - v; | |
91 | +} | |
92 | + | |
93 | +void OPPROTO glue(glue(op_repz_scas, SUFFIX), STRING_SUFFIX)(void) | |
94 | +{ | |
95 | + int v1, v2, inc; | |
96 | + | |
97 | + if (CX != 0) { | |
98 | + /* NOTE: the flags are not modified if CX == 0 */ | |
99 | + v1 = EAX & DATA_MASK; | |
100 | + inc = (DF << SHIFT); | |
101 | + do { | |
102 | + v2 = glue(ldu, SUFFIX)(DI_ADDR); | |
103 | + INC_DI(); | |
104 | + DEC_CX(); | |
105 | + if (v1 != v2) | |
106 | + break; | |
107 | + } while (CX != 0); | |
108 | + CC_SRC = v1; | |
109 | + CC_DST = v1 - v2; | |
110 | + CC_OP = CC_OP_SUBB + SHIFT; | |
111 | + } | |
112 | + FORCE_RET(); | |
113 | +} | |
114 | + | |
115 | +void OPPROTO glue(glue(op_repnz_scas, SUFFIX), STRING_SUFFIX)(void) | |
116 | +{ | |
117 | + int v1, v2, inc; | |
118 | + | |
119 | + if (CX != 0) { | |
120 | + /* NOTE: the flags are not modified if CX == 0 */ | |
121 | + v1 = EAX & DATA_MASK; | |
122 | + inc = (DF << SHIFT); | |
123 | + do { | |
124 | + v2 = glue(ldu, SUFFIX)(DI_ADDR); | |
125 | + INC_DI(); | |
126 | + DEC_CX(); | |
127 | + if (v1 == v2) | |
128 | + break; | |
129 | + } while (CX != 0); | |
130 | + CC_SRC = v1; | |
131 | + CC_DST = v1 - v2; | |
132 | + CC_OP = CC_OP_SUBB + SHIFT; | |
133 | + } | |
134 | + FORCE_RET(); | |
135 | +} | |
136 | + | |
137 | +void OPPROTO glue(glue(op_cmps, SUFFIX), STRING_SUFFIX)(void) | |
138 | +{ | |
139 | + int v1, v2, inc; | |
140 | + v1 = glue(ldu, SUFFIX)(SI_ADDR); | |
141 | + v2 = glue(ldu, SUFFIX)(DI_ADDR); | |
142 | + inc = (DF << SHIFT); | |
143 | + INC_SI(); | |
144 | + INC_DI(); | |
145 | + CC_SRC = v1; | |
146 | + CC_DST = v1 - v2; | |
147 | +} | |
148 | + | |
149 | +void OPPROTO glue(glue(op_repz_cmps, SUFFIX), STRING_SUFFIX)(void) | |
150 | +{ | |
151 | + int v1, v2, inc; | |
152 | + if (CX != 0) { | |
153 | + inc = (DF << SHIFT); | |
154 | + do { | |
155 | + v1 = glue(ldu, SUFFIX)(SI_ADDR); | |
156 | + v2 = glue(ldu, SUFFIX)(DI_ADDR); | |
157 | + INC_SI(); | |
158 | + INC_DI(); | |
159 | + DEC_CX(); | |
160 | + if (v1 != v2) | |
161 | + break; | |
162 | + } while (CX != 0); | |
163 | + CC_SRC = v1; | |
164 | + CC_DST = v1 - v2; | |
165 | + CC_OP = CC_OP_SUBB + SHIFT; | |
166 | + } | |
167 | + FORCE_RET(); | |
168 | +} | |
169 | + | |
170 | +void OPPROTO glue(glue(op_repnz_cmps, SUFFIX), STRING_SUFFIX)(void) | |
171 | +{ | |
172 | + int v1, v2, inc; | |
173 | + if (CX != 0) { | |
174 | + inc = (DF << SHIFT); | |
175 | + do { | |
176 | + v1 = glue(ldu, SUFFIX)(SI_ADDR); | |
177 | + v2 = glue(ldu, SUFFIX)(DI_ADDR); | |
178 | + INC_SI(); | |
179 | + INC_DI(); | |
180 | + DEC_CX(); | |
181 | + if (v1 == v2) | |
182 | + break; | |
183 | + } while (CX != 0); | |
184 | + CC_SRC = v1; | |
185 | + CC_DST = v1 - v2; | |
186 | + CC_OP = CC_OP_SUBB + SHIFT; | |
187 | + } | |
188 | + FORCE_RET(); | |
189 | +} | |
190 | + | |
191 | +void OPPROTO glue(glue(op_outs, SUFFIX), STRING_SUFFIX)(void) | |
192 | +{ | |
193 | + int v, dx, inc; | |
194 | + dx = EDX & 0xffff; | |
195 | + v = glue(ldu, SUFFIX)(SI_ADDR); | |
196 | + glue(cpu_x86_out, SUFFIX)(dx, v); | |
197 | + inc = (DF << SHIFT); | |
198 | + INC_SI(); | |
199 | +} | |
200 | + | |
201 | +void OPPROTO glue(glue(op_rep_outs, SUFFIX), STRING_SUFFIX)(void) | |
202 | +{ | |
203 | + int v, dx, inc; | |
204 | + inc = (DF << SHIFT); | |
205 | + dx = EDX & 0xffff; | |
206 | + while (CX != 0) { | |
207 | + v = glue(ldu, SUFFIX)(SI_ADDR); | |
208 | + glue(cpu_x86_out, SUFFIX)(dx, v); | |
209 | + INC_SI(); | |
210 | + DEC_CX(); | |
211 | + } | |
212 | + FORCE_RET(); | |
213 | +} | |
214 | + | |
215 | +void OPPROTO glue(glue(op_ins, SUFFIX), STRING_SUFFIX)(void) | |
216 | +{ | |
217 | + int v, dx, inc; | |
218 | + dx = EDX & 0xffff; | |
219 | + v = glue(cpu_x86_in, SUFFIX)(dx); | |
220 | + glue(st, SUFFIX)(DI_ADDR, v); | |
221 | + inc = (DF << SHIFT); | |
222 | + INC_DI(); | |
223 | +} | |
224 | + | |
225 | +void OPPROTO glue(glue(op_rep_ins, SUFFIX), STRING_SUFFIX)(void) | |
226 | +{ | |
227 | + int v, dx, inc; | |
228 | + inc = (DF << SHIFT); | |
229 | + dx = EDX & 0xffff; | |
230 | + while (CX != 0) { | |
231 | + v = glue(cpu_x86_in, SUFFIX)(dx); | |
232 | + glue(st, SUFFIX)(DI_ADDR, v); | |
233 | + INC_DI(); | |
234 | + DEC_CX(); | |
235 | + } | |
236 | + FORCE_RET(); | |
237 | +} | |
238 | + | |
239 | +#undef STRING_SUFFIX | |
240 | +#undef SI_ADDR | |
241 | +#undef DI_ADDR | |
242 | +#undef INC_SI | |
243 | +#undef INC_DI | |
244 | +#undef CX | |
245 | +#undef DEC_CX | ... | ... |
ops_template.h
... | ... | @@ -806,238 +806,37 @@ void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void) |
806 | 806 | #endif |
807 | 807 | |
808 | 808 | /* string operations */ |
809 | -/* XXX: maybe use lower level instructions to ease exception handling */ | |
810 | - | |
811 | -void OPPROTO glue(op_movs, SUFFIX)(void) | |
812 | -{ | |
813 | - int v; | |
814 | - v = glue(ldu, SUFFIX)((void *)ESI); | |
815 | - glue(st, SUFFIX)((void *)EDI, v); | |
816 | - ESI += (DF << SHIFT); | |
817 | - EDI += (DF << SHIFT); | |
818 | -} | |
819 | - | |
820 | -void OPPROTO glue(op_rep_movs, SUFFIX)(void) | |
821 | -{ | |
822 | - int v, inc; | |
823 | - inc = (DF << SHIFT); | |
824 | - while (ECX != 0) { | |
825 | - v = glue(ldu, SUFFIX)((void *)ESI); | |
826 | - glue(st, SUFFIX)((void *)EDI, v); | |
827 | - ESI += inc; | |
828 | - EDI += inc; | |
829 | - ECX--; | |
830 | - } | |
831 | - FORCE_RET(); | |
832 | -} | |
833 | - | |
834 | -void OPPROTO glue(op_stos, SUFFIX)(void) | |
835 | -{ | |
836 | - glue(st, SUFFIX)((void *)EDI, EAX); | |
837 | - EDI += (DF << SHIFT); | |
838 | -} | |
839 | - | |
840 | -void OPPROTO glue(op_rep_stos, SUFFIX)(void) | |
841 | -{ | |
842 | - int inc; | |
843 | - inc = (DF << SHIFT); | |
844 | - while (ECX != 0) { | |
845 | - glue(st, SUFFIX)((void *)EDI, EAX); | |
846 | - EDI += inc; | |
847 | - ECX--; | |
848 | - } | |
849 | - FORCE_RET(); | |
850 | -} | |
851 | - | |
852 | -void OPPROTO glue(op_lods, SUFFIX)(void) | |
853 | -{ | |
854 | - int v; | |
855 | - v = glue(ldu, SUFFIX)((void *)ESI); | |
856 | -#if SHIFT == 0 | |
857 | - EAX = (EAX & ~0xff) | v; | |
858 | -#elif SHIFT == 1 | |
859 | - EAX = (EAX & ~0xffff) | v; | |
860 | -#else | |
861 | - EAX = v; | |
862 | -#endif | |
863 | - ESI += (DF << SHIFT); | |
864 | -} | |
865 | - | |
866 | -/* don't know if it is used */ | |
867 | -void OPPROTO glue(op_rep_lods, SUFFIX)(void) | |
868 | -{ | |
869 | - int v, inc; | |
870 | - inc = (DF << SHIFT); | |
871 | - while (ECX != 0) { | |
872 | - v = glue(ldu, SUFFIX)((void *)ESI); | |
873 | -#if SHIFT == 0 | |
874 | - EAX = (EAX & ~0xff) | v; | |
875 | -#elif SHIFT == 1 | |
876 | - EAX = (EAX & ~0xffff) | v; | |
877 | -#else | |
878 | - EAX = v; | |
879 | -#endif | |
880 | - ESI += inc; | |
881 | - ECX--; | |
882 | - } | |
883 | - FORCE_RET(); | |
884 | -} | |
885 | - | |
886 | -void OPPROTO glue(op_scas, SUFFIX)(void) | |
887 | -{ | |
888 | - int v; | |
889 | - | |
890 | - v = glue(ldu, SUFFIX)((void *)EDI); | |
891 | - EDI += (DF << SHIFT); | |
892 | - CC_SRC = EAX; | |
893 | - CC_DST = EAX - v; | |
894 | -} | |
895 | - | |
896 | -void OPPROTO glue(op_repz_scas, SUFFIX)(void) | |
897 | -{ | |
898 | - int v1, v2, inc; | |
899 | - | |
900 | - if (ECX != 0) { | |
901 | - /* NOTE: the flags are not modified if ECX == 0 */ | |
902 | - v1 = EAX & DATA_MASK; | |
903 | - inc = (DF << SHIFT); | |
904 | - do { | |
905 | - v2 = glue(ldu, SUFFIX)((void *)EDI); | |
906 | - EDI += inc; | |
907 | - ECX--; | |
908 | - if (v1 != v2) | |
909 | - break; | |
910 | - } while (ECX != 0); | |
911 | - CC_SRC = v1; | |
912 | - CC_DST = v1 - v2; | |
913 | - CC_OP = CC_OP_SUBB + SHIFT; | |
914 | - } | |
915 | - FORCE_RET(); | |
916 | -} | |
917 | - | |
918 | -void OPPROTO glue(op_repnz_scas, SUFFIX)(void) | |
919 | -{ | |
920 | - int v1, v2, inc; | |
921 | - | |
922 | - if (ECX != 0) { | |
923 | - /* NOTE: the flags are not modified if ECX == 0 */ | |
924 | - v1 = EAX & DATA_MASK; | |
925 | - inc = (DF << SHIFT); | |
926 | - do { | |
927 | - v2 = glue(ldu, SUFFIX)((void *)EDI); | |
928 | - EDI += inc; | |
929 | - ECX--; | |
930 | - if (v1 == v2) | |
931 | - break; | |
932 | - } while (ECX != 0); | |
933 | - CC_SRC = v1; | |
934 | - CC_DST = v1 - v2; | |
935 | - CC_OP = CC_OP_SUBB + SHIFT; | |
936 | - } | |
937 | - FORCE_RET(); | |
938 | -} | |
939 | - | |
940 | -void OPPROTO glue(op_cmps, SUFFIX)(void) | |
941 | -{ | |
942 | - int v1, v2; | |
943 | - v1 = glue(ldu, SUFFIX)((void *)ESI); | |
944 | - v2 = glue(ldu, SUFFIX)((void *)EDI); | |
945 | - ESI += (DF << SHIFT); | |
946 | - EDI += (DF << SHIFT); | |
947 | - CC_SRC = v1; | |
948 | - CC_DST = v1 - v2; | |
949 | -} | |
950 | - | |
951 | -void OPPROTO glue(op_repz_cmps, SUFFIX)(void) | |
952 | -{ | |
953 | - int v1, v2, inc; | |
954 | - if (ECX != 0) { | |
955 | - inc = (DF << SHIFT); | |
956 | - do { | |
957 | - v1 = glue(ldu, SUFFIX)((void *)ESI); | |
958 | - v2 = glue(ldu, SUFFIX)((void *)EDI); | |
959 | - ESI += inc; | |
960 | - EDI += inc; | |
961 | - ECX--; | |
962 | - if (v1 != v2) | |
963 | - break; | |
964 | - } while (ECX != 0); | |
965 | - CC_SRC = v1; | |
966 | - CC_DST = v1 - v2; | |
967 | - CC_OP = CC_OP_SUBB + SHIFT; | |
968 | - } | |
969 | - FORCE_RET(); | |
970 | -} | |
971 | - | |
972 | -void OPPROTO glue(op_repnz_cmps, SUFFIX)(void) | |
973 | -{ | |
974 | - int v1, v2, inc; | |
975 | - if (ECX != 0) { | |
976 | - inc = (DF << SHIFT); | |
977 | - do { | |
978 | - v1 = glue(ldu, SUFFIX)((void *)ESI); | |
979 | - v2 = glue(ldu, SUFFIX)((void *)EDI); | |
980 | - ESI += inc; | |
981 | - EDI += inc; | |
982 | - ECX--; | |
983 | - if (v1 == v2) | |
984 | - break; | |
985 | - } while (ECX != 0); | |
986 | - CC_SRC = v1; | |
987 | - CC_DST = v1 - v2; | |
988 | - CC_OP = CC_OP_SUBB + SHIFT; | |
989 | - } | |
990 | - FORCE_RET(); | |
991 | -} | |
809 | +/* XXX: maybe use lower level instructions to ease 16 bit / segment handling */ | |
810 | + | |
811 | +#define STRING_SUFFIX _fast | |
812 | +#define SI_ADDR (void *)ESI | |
813 | +#define DI_ADDR (void *)EDI | |
814 | +#define INC_SI() ESI += inc | |
815 | +#define INC_DI() EDI += inc | |
816 | +#define CX ECX | |
817 | +#define DEC_CX() ECX-- | |
818 | +#include "op_string.h" | |
819 | + | |
820 | +#define STRING_SUFFIX _a32 | |
821 | +#define SI_ADDR (uint8_t *)A0 + ESI | |
822 | +#define DI_ADDR env->seg_cache[R_ES].base + EDI | |
823 | +#define INC_SI() ESI += inc | |
824 | +#define INC_DI() EDI += inc | |
825 | +#define CX ECX | |
826 | +#define DEC_CX() ECX-- | |
827 | +#include "op_string.h" | |
828 | + | |
829 | +#define STRING_SUFFIX _a16 | |
830 | +#define SI_ADDR (uint8_t *)A0 + (ESI & 0xffff) | |
831 | +#define DI_ADDR env->seg_cache[R_ES].base + (EDI & 0xffff) | |
832 | +#define INC_SI() ESI = (ESI & ~0xffff) | ((ESI + inc) & 0xffff) | |
833 | +#define INC_DI() EDI = (EDI & ~0xffff) | ((EDI + inc) & 0xffff) | |
834 | +#define CX (ECX & 0xffff) | |
835 | +#define DEC_CX() ECX = (ECX & ~0xffff) | ((ECX - 1) & 0xffff) | |
836 | +#include "op_string.h" | |
992 | 837 | |
993 | 838 | /* port I/O */ |
994 | 839 | |
995 | -void OPPROTO glue(op_outs, SUFFIX)(void) | |
996 | -{ | |
997 | - int v, dx; | |
998 | - dx = EDX & 0xffff; | |
999 | - v = glue(ldu, SUFFIX)((void *)ESI); | |
1000 | - glue(cpu_x86_out, SUFFIX)(dx, v); | |
1001 | - ESI += (DF << SHIFT); | |
1002 | -} | |
1003 | - | |
1004 | -void OPPROTO glue(op_rep_outs, SUFFIX)(void) | |
1005 | -{ | |
1006 | - int v, dx, inc; | |
1007 | - inc = (DF << SHIFT); | |
1008 | - dx = EDX & 0xffff; | |
1009 | - while (ECX != 0) { | |
1010 | - v = glue(ldu, SUFFIX)((void *)ESI); | |
1011 | - glue(cpu_x86_out, SUFFIX)(dx, v); | |
1012 | - ESI += inc; | |
1013 | - ECX--; | |
1014 | - } | |
1015 | - FORCE_RET(); | |
1016 | -} | |
1017 | - | |
1018 | -void OPPROTO glue(op_ins, SUFFIX)(void) | |
1019 | -{ | |
1020 | - int v, dx; | |
1021 | - dx = EDX & 0xffff; | |
1022 | - v = glue(cpu_x86_in, SUFFIX)(dx); | |
1023 | - glue(st, SUFFIX)((void *)EDI, v); | |
1024 | - EDI += (DF << SHIFT); | |
1025 | -} | |
1026 | - | |
1027 | -void OPPROTO glue(op_rep_ins, SUFFIX)(void) | |
1028 | -{ | |
1029 | - int v, dx, inc; | |
1030 | - inc = (DF << SHIFT); | |
1031 | - dx = EDX & 0xffff; | |
1032 | - while (ECX != 0) { | |
1033 | - v = glue(cpu_x86_in, SUFFIX)(dx); | |
1034 | - glue(st, SUFFIX)((void *)EDI, v); | |
1035 | - EDI += (DF << SHIFT); | |
1036 | - ECX--; | |
1037 | - } | |
1038 | - FORCE_RET(); | |
1039 | -} | |
1040 | - | |
1041 | 840 | void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void) |
1042 | 841 | { |
1043 | 842 | glue(cpu_x86_out, SUFFIX)(T0 & 0xffff, T1 & DATA_MASK); | ... | ... |