Commit 24f9e90b0e183d501ff77c6851cbe11e7d7254a1

Authored by bellard
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,238 +806,37 @@ void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void)
806 #endif 806 #endif
807 807
808 /* string operations */ 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 /* port I/O */ 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 void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void) 840 void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void)
1042 { 841 {
1043 glue(cpu_x86_out, SUFFIX)(T0 & 0xffff, T1 & DATA_MASK); 842 glue(cpu_x86_out, SUFFIX)(T0 & 0xffff, T1 & DATA_MASK);