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 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);
... ...