16bit/override support in string operations
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sat, 29 Mar 2003 16:50:40 +0000 (16:50 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sat, 29 Mar 2003 16:50:40 +0000 (16:50 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@54 c046a42c-6fe2-441c-8c8c-71466251a162

op_string.h [new file with mode: 0644]
ops_template.h

diff --git a/op_string.h b/op_string.h
new file mode 100644 (file)
index 0000000..9d0b454
--- /dev/null
@@ -0,0 +1,245 @@
+
+void OPPROTO glue(glue(op_movs, SUFFIX), STRING_SUFFIX)(void)
+{
+    int v, inc;
+    inc = (DF << SHIFT);
+    v = glue(ldu, SUFFIX)(SI_ADDR);
+    glue(st, SUFFIX)(DI_ADDR, v);
+    inc = (DF << SHIFT);
+    INC_SI();
+    INC_DI();
+}
+
+void OPPROTO glue(glue(op_rep_movs, SUFFIX), STRING_SUFFIX)(void)
+{
+    int v, inc;
+    inc = (DF << SHIFT);
+    while (CX != 0) {
+        v = glue(ldu, SUFFIX)(SI_ADDR);
+        glue(st, SUFFIX)(DI_ADDR, v);
+        INC_SI();
+        INC_DI();
+        DEC_CX();
+    }
+    FORCE_RET();
+}
+
+void OPPROTO glue(glue(op_stos, SUFFIX), STRING_SUFFIX)(void)
+{
+    int inc;
+    glue(st, SUFFIX)(DI_ADDR, EAX);
+    inc = (DF << SHIFT);
+    INC_DI();
+}
+
+void OPPROTO glue(glue(op_rep_stos, SUFFIX), STRING_SUFFIX)(void)
+{
+    int inc;
+    inc = (DF << SHIFT);
+    while (CX != 0) {
+        glue(st, SUFFIX)(DI_ADDR, EAX);
+        INC_DI();
+        DEC_CX();
+    }
+    FORCE_RET();
+}
+
+void OPPROTO glue(glue(op_lods, SUFFIX), STRING_SUFFIX)(void)
+{
+    int v, inc;
+    v = glue(ldu, SUFFIX)(SI_ADDR);
+#if SHIFT == 0
+    EAX = (EAX & ~0xff) | v;
+#elif SHIFT == 1
+    EAX = (EAX & ~0xffff) | v;
+#else
+    EAX = v;
+#endif
+    inc = (DF << SHIFT);
+    INC_SI();
+}
+
+/* don't know if it is used */
+void OPPROTO glue(glue(op_rep_lods, SUFFIX), STRING_SUFFIX)(void)
+{
+    int v, inc;
+    inc = (DF << SHIFT);
+    while (CX != 0) {
+        v = glue(ldu, SUFFIX)(SI_ADDR);
+#if SHIFT == 0
+        EAX = (EAX & ~0xff) | v;
+#elif SHIFT == 1
+        EAX = (EAX & ~0xffff) | v;
+#else
+        EAX = v;
+#endif
+        INC_SI();
+        DEC_CX();
+    }
+    FORCE_RET();
+}
+
+void OPPROTO glue(glue(op_scas, SUFFIX), STRING_SUFFIX)(void)
+{
+    int v, inc;
+
+    v = glue(ldu, SUFFIX)(DI_ADDR);
+    inc = (DF << SHIFT);
+    INC_DI();
+    CC_SRC = EAX;
+    CC_DST = EAX - v;
+}
+
+void OPPROTO glue(glue(op_repz_scas, SUFFIX), STRING_SUFFIX)(void)
+{
+    int v1, v2, inc;
+
+    if (CX != 0) {
+        /* NOTE: the flags are not modified if CX == 0 */
+        v1 = EAX & DATA_MASK;
+        inc = (DF << SHIFT);
+        do {
+            v2 = glue(ldu, SUFFIX)(DI_ADDR);
+            INC_DI();
+            DEC_CX();
+            if (v1 != v2)
+                break;
+        } while (CX != 0);
+        CC_SRC = v1;
+        CC_DST = v1 - v2;
+        CC_OP = CC_OP_SUBB + SHIFT;
+    }
+    FORCE_RET();
+}
+
+void OPPROTO glue(glue(op_repnz_scas, SUFFIX), STRING_SUFFIX)(void)
+{
+    int v1, v2, inc;
+
+    if (CX != 0) {
+        /* NOTE: the flags are not modified if CX == 0 */
+        v1 = EAX & DATA_MASK;
+        inc = (DF << SHIFT);
+        do {
+            v2 = glue(ldu, SUFFIX)(DI_ADDR);
+            INC_DI();
+            DEC_CX();
+            if (v1 == v2)
+                break;
+        } while (CX != 0);
+        CC_SRC = v1;
+        CC_DST = v1 - v2;
+        CC_OP = CC_OP_SUBB + SHIFT;
+    }
+    FORCE_RET();
+}
+
+void OPPROTO glue(glue(op_cmps, SUFFIX), STRING_SUFFIX)(void)
+{
+    int v1, v2, inc;
+    v1 = glue(ldu, SUFFIX)(SI_ADDR);
+    v2 = glue(ldu, SUFFIX)(DI_ADDR);
+    inc = (DF << SHIFT);
+    INC_SI();
+    INC_DI();
+    CC_SRC = v1;
+    CC_DST = v1 - v2;
+}
+
+void OPPROTO glue(glue(op_repz_cmps, SUFFIX), STRING_SUFFIX)(void)
+{
+    int v1, v2, inc;
+    if (CX != 0) {
+        inc = (DF << SHIFT);
+        do {
+            v1 = glue(ldu, SUFFIX)(SI_ADDR);
+            v2 = glue(ldu, SUFFIX)(DI_ADDR);
+            INC_SI();
+            INC_DI();
+            DEC_CX();
+            if (v1 != v2)
+                break;
+        } while (CX != 0);
+        CC_SRC = v1;
+        CC_DST = v1 - v2;
+        CC_OP = CC_OP_SUBB + SHIFT;
+    }
+    FORCE_RET();
+}
+
+void OPPROTO glue(glue(op_repnz_cmps, SUFFIX), STRING_SUFFIX)(void)
+{
+    int v1, v2, inc;
+    if (CX != 0) {
+        inc = (DF << SHIFT);
+        do {
+            v1 = glue(ldu, SUFFIX)(SI_ADDR);
+            v2 = glue(ldu, SUFFIX)(DI_ADDR);
+            INC_SI();
+            INC_DI();
+            DEC_CX();
+            if (v1 == v2)
+                break;
+        } while (CX != 0);
+        CC_SRC = v1;
+        CC_DST = v1 - v2;
+        CC_OP = CC_OP_SUBB + SHIFT;
+    }
+    FORCE_RET();
+}
+
+void OPPROTO glue(glue(op_outs, SUFFIX), STRING_SUFFIX)(void)
+{
+    int v, dx, inc;
+    dx = EDX & 0xffff;
+    v = glue(ldu, SUFFIX)(SI_ADDR);
+    glue(cpu_x86_out, SUFFIX)(dx, v);
+    inc = (DF << SHIFT);
+    INC_SI();
+}
+
+void OPPROTO glue(glue(op_rep_outs, SUFFIX), STRING_SUFFIX)(void)
+{
+    int v, dx, inc;
+    inc = (DF << SHIFT);
+    dx = EDX & 0xffff;
+    while (CX != 0) {
+        v = glue(ldu, SUFFIX)(SI_ADDR);
+        glue(cpu_x86_out, SUFFIX)(dx, v);
+        INC_SI();
+        DEC_CX();
+    }
+    FORCE_RET();
+}
+
+void OPPROTO glue(glue(op_ins, SUFFIX), STRING_SUFFIX)(void)
+{
+    int v, dx, inc;
+    dx = EDX & 0xffff;
+    v = glue(cpu_x86_in, SUFFIX)(dx);
+    glue(st, SUFFIX)(DI_ADDR, v);
+    inc = (DF << SHIFT);
+    INC_DI();
+}
+
+void OPPROTO glue(glue(op_rep_ins, SUFFIX), STRING_SUFFIX)(void)
+{
+    int v, dx, inc;
+    inc = (DF << SHIFT);
+    dx = EDX & 0xffff;
+    while (CX != 0) {
+        v = glue(cpu_x86_in, SUFFIX)(dx);
+        glue(st, SUFFIX)(DI_ADDR, v);
+        INC_DI();
+        DEC_CX();
+    }
+    FORCE_RET();
+}
+
+#undef STRING_SUFFIX
+#undef SI_ADDR
+#undef DI_ADDR
+#undef INC_SI
+#undef INC_DI
+#undef CX
+#undef DEC_CX
index 34f10cdf936e93a72de3370dd7a4618050f5684a..60223fb2fffed103896fb6b54bc15039633c9bb2 100644 (file)
@@ -806,238 +806,37 @@ void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void)
 #endif
 
 /* string operations */
-/* XXX: maybe use lower level instructions to ease exception handling */
-
-void OPPROTO glue(op_movs, SUFFIX)(void)
-{
-    int v;
-    v = glue(ldu, SUFFIX)((void *)ESI);
-    glue(st, SUFFIX)((void *)EDI, v);
-    ESI += (DF << SHIFT);
-    EDI += (DF << SHIFT);
-}
-
-void OPPROTO glue(op_rep_movs, SUFFIX)(void)
-{
-    int v, inc;
-    inc = (DF << SHIFT);
-    while (ECX != 0) {
-        v = glue(ldu, SUFFIX)((void *)ESI);
-        glue(st, SUFFIX)((void *)EDI, v);
-        ESI += inc;
-        EDI += inc;
-        ECX--;
-    }
-    FORCE_RET();
-}
-
-void OPPROTO glue(op_stos, SUFFIX)(void)
-{
-    glue(st, SUFFIX)((void *)EDI, EAX);
-    EDI += (DF << SHIFT);
-}
-
-void OPPROTO glue(op_rep_stos, SUFFIX)(void)
-{
-    int inc;
-    inc = (DF << SHIFT);
-    while (ECX != 0) {
-        glue(st, SUFFIX)((void *)EDI, EAX);
-        EDI += inc;
-        ECX--;
-    }
-    FORCE_RET();
-}
-
-void OPPROTO glue(op_lods, SUFFIX)(void)
-{
-    int v;
-    v = glue(ldu, SUFFIX)((void *)ESI);
-#if SHIFT == 0
-    EAX = (EAX & ~0xff) | v;
-#elif SHIFT == 1
-    EAX = (EAX & ~0xffff) | v;
-#else
-    EAX = v;
-#endif
-    ESI += (DF << SHIFT);
-}
-
-/* don't know if it is used */
-void OPPROTO glue(op_rep_lods, SUFFIX)(void)
-{
-    int v, inc;
-    inc = (DF << SHIFT);
-    while (ECX != 0) {
-        v = glue(ldu, SUFFIX)((void *)ESI);
-#if SHIFT == 0
-        EAX = (EAX & ~0xff) | v;
-#elif SHIFT == 1
-        EAX = (EAX & ~0xffff) | v;
-#else
-        EAX = v;
-#endif
-        ESI += inc;
-        ECX--;
-    }
-    FORCE_RET();
-}
-
-void OPPROTO glue(op_scas, SUFFIX)(void)
-{
-    int v;
-
-    v = glue(ldu, SUFFIX)((void *)EDI);
-    EDI += (DF << SHIFT);
-    CC_SRC = EAX;
-    CC_DST = EAX - v;
-}
-
-void OPPROTO glue(op_repz_scas, SUFFIX)(void)
-{
-    int v1, v2, inc;
-
-    if (ECX != 0) {
-        /* NOTE: the flags are not modified if ECX == 0 */
-        v1 = EAX & DATA_MASK;
-        inc = (DF << SHIFT);
-        do {
-            v2 = glue(ldu, SUFFIX)((void *)EDI);
-            EDI += inc;
-            ECX--;
-            if (v1 != v2)
-                break;
-        } while (ECX != 0);
-        CC_SRC = v1;
-        CC_DST = v1 - v2;
-        CC_OP = CC_OP_SUBB + SHIFT;
-    }
-    FORCE_RET();
-}
-
-void OPPROTO glue(op_repnz_scas, SUFFIX)(void)
-{
-    int v1, v2, inc;
-
-    if (ECX != 0) {
-        /* NOTE: the flags are not modified if ECX == 0 */
-        v1 = EAX & DATA_MASK;
-        inc = (DF << SHIFT);
-        do {
-            v2 = glue(ldu, SUFFIX)((void *)EDI);
-            EDI += inc;
-            ECX--;
-            if (v1 == v2)
-                break;
-        } while (ECX != 0);
-        CC_SRC = v1;
-        CC_DST = v1 - v2;
-        CC_OP = CC_OP_SUBB + SHIFT;
-    }
-    FORCE_RET();
-}
-
-void OPPROTO glue(op_cmps, SUFFIX)(void)
-{
-    int v1, v2;
-    v1 = glue(ldu, SUFFIX)((void *)ESI);
-    v2 = glue(ldu, SUFFIX)((void *)EDI);
-    ESI += (DF << SHIFT);
-    EDI += (DF << SHIFT);
-    CC_SRC = v1;
-    CC_DST = v1 - v2;
-}
-
-void OPPROTO glue(op_repz_cmps, SUFFIX)(void)
-{
-    int v1, v2, inc;
-    if (ECX != 0) {
-        inc = (DF << SHIFT);
-        do {
-            v1 = glue(ldu, SUFFIX)((void *)ESI);
-            v2 = glue(ldu, SUFFIX)((void *)EDI);
-            ESI += inc;
-            EDI += inc;
-            ECX--;
-            if (v1 != v2)
-                break;
-        } while (ECX != 0);
-        CC_SRC = v1;
-        CC_DST = v1 - v2;
-        CC_OP = CC_OP_SUBB + SHIFT;
-    }
-    FORCE_RET();
-}
-
-void OPPROTO glue(op_repnz_cmps, SUFFIX)(void)
-{
-    int v1, v2, inc;
-    if (ECX != 0) {
-        inc = (DF << SHIFT);
-        do {
-            v1 = glue(ldu, SUFFIX)((void *)ESI);
-            v2 = glue(ldu, SUFFIX)((void *)EDI);
-            ESI += inc;
-            EDI += inc;
-            ECX--;
-            if (v1 == v2)
-                break;
-        } while (ECX != 0);
-        CC_SRC = v1;
-        CC_DST = v1 - v2;
-        CC_OP = CC_OP_SUBB + SHIFT;
-    }
-    FORCE_RET();
-}
+/* XXX: maybe use lower level instructions to ease 16 bit / segment handling */
+
+#define STRING_SUFFIX _fast
+#define SI_ADDR (void *)ESI
+#define DI_ADDR (void *)EDI
+#define INC_SI() ESI += inc
+#define INC_DI() EDI += inc
+#define CX ECX
+#define DEC_CX() ECX--
+#include "op_string.h"
+
+#define STRING_SUFFIX _a32
+#define SI_ADDR (uint8_t *)A0 + ESI
+#define DI_ADDR env->seg_cache[R_ES].base + EDI
+#define INC_SI() ESI += inc
+#define INC_DI() EDI += inc
+#define CX ECX
+#define DEC_CX() ECX--
+#include "op_string.h"
+
+#define STRING_SUFFIX _a16
+#define SI_ADDR (uint8_t *)A0 + (ESI & 0xffff)
+#define DI_ADDR env->seg_cache[R_ES].base + (EDI & 0xffff)
+#define INC_SI() ESI = (ESI & ~0xffff) | ((ESI + inc) & 0xffff)
+#define INC_DI() EDI = (EDI & ~0xffff) | ((EDI + inc) & 0xffff)
+#define CX (ECX & 0xffff)
+#define DEC_CX() ECX = (ECX & ~0xffff) | ((ECX - 1) & 0xffff)
+#include "op_string.h"
 
 /* port I/O */
 
-void OPPROTO glue(op_outs, SUFFIX)(void)
-{
-    int v, dx;
-    dx = EDX & 0xffff;
-    v = glue(ldu, SUFFIX)((void *)ESI);
-    glue(cpu_x86_out, SUFFIX)(dx, v);
-    ESI += (DF << SHIFT);
-}
-
-void OPPROTO glue(op_rep_outs, SUFFIX)(void)
-{
-    int v, dx, inc;
-    inc = (DF << SHIFT);
-    dx = EDX & 0xffff;
-    while (ECX != 0) {
-        v = glue(ldu, SUFFIX)((void *)ESI);
-        glue(cpu_x86_out, SUFFIX)(dx, v);
-        ESI += inc;
-        ECX--;
-    }
-    FORCE_RET();
-}
-
-void OPPROTO glue(op_ins, SUFFIX)(void)
-{
-    int v, dx;
-    dx = EDX & 0xffff;
-    v = glue(cpu_x86_in, SUFFIX)(dx);
-    glue(st, SUFFIX)((void *)EDI, v);
-    EDI += (DF << SHIFT);
-}
-
-void OPPROTO glue(op_rep_ins, SUFFIX)(void)
-{
-    int v, dx, inc;
-    inc = (DF << SHIFT);
-    dx = EDX & 0xffff;
-    while (ECX != 0) {
-        v = glue(cpu_x86_in, SUFFIX)(dx);
-        glue(st, SUFFIX)((void *)EDI, v);
-        EDI += (DF << SHIFT);
-        ECX--;
-    }
-    FORCE_RET();
-}
-
 void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void)
 {
     glue(cpu_x86_out, SUFFIX)(T0 & 0xffff, T1 & DATA_MASK);