]> Git Repo - qemu.git/blobdiff - op-i386.c
added VGA emulation - added PS/2 mouse and keyboard emulation - use SDL for VGA display
[qemu.git] / op-i386.c
index e3f26b4e02931f91a191a2b4f9611b695a96b2b3..60ae5e55f29a237281eafac2abf4059b5a281fea 100644 (file)
--- a/op-i386.c
+++ b/op-i386.c
  */
 #include "exec-i386.h"
 
-uint8_t parity_table[256] = {
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-};
-
-/* modulo 17 table */
-const uint8_t rclw_table[32] = {
-    0, 1, 2, 3, 4, 5, 6, 7, 
-    8, 9,10,11,12,13,14,15,
-   16, 0, 1, 2, 3, 4, 5, 6,
-    7, 8, 9,10,11,12,13,14,
-};
-
-/* modulo 9 table */
-const uint8_t rclb_table[32] = {
-    0, 1, 2, 3, 4, 5, 6, 7, 
-    8, 0, 1, 2, 3, 4, 5, 6,
-    7, 8, 0, 1, 2, 3, 4, 5, 
-    6, 7, 8, 0, 1, 2, 3, 4,
-};
-
 /* n must be a constant to be efficient */
 static inline int lshift(int x, int n)
 {
@@ -131,62 +80,34 @@ static inline int lshift(int x, int n)
 
 /* operations with flags */
 
-void OPPROTO op_addl_T0_T1_cc(void)
+/* update flags with T0 and T1 (add/sub case) */
+void OPPROTO op_update2_cc(void)
 {
-    CC_SRC = T0;
-    T0 += T1;
+    CC_SRC = T1;
     CC_DST = T0;
 }
 
-void OPPROTO op_orl_T0_T1_cc(void)
+/* update flags with T0 (logic operation case) */
+void OPPROTO op_update1_cc(void)
 {
-    T0 |= T1;
     CC_DST = T0;
 }
 
-void OPPROTO op_andl_T0_T1_cc(void)
+void OPPROTO op_update_neg_cc(void)
 {
-    T0 &= T1;
-    CC_DST = T0;
-}
-
-void OPPROTO op_subl_T0_T1_cc(void)
-{
-    CC_SRC = T0;
-    T0 -= T1;
-    CC_DST = T0;
-}
-
-void OPPROTO op_xorl_T0_T1_cc(void)
-{
-    T0 ^= T1;
+    CC_SRC = -T0;
     CC_DST = T0;
 }
 
 void OPPROTO op_cmpl_T0_T1_cc(void)
 {
-    CC_SRC = T0;
+    CC_SRC = T1;
     CC_DST = T0 - T1;
 }
 
-void OPPROTO op_negl_T0_cc(void)
-{
-    CC_SRC = 0;
-    T0 = -T0;
-    CC_DST = T0;
-}
-
-void OPPROTO op_incl_T0_cc(void)
+void OPPROTO op_update_inc_cc(void)
 {
     CC_SRC = cc_table[CC_OP].compute_c();
-    T0++;
-    CC_DST = T0;
-}
-
-void OPPROTO op_decl_T0_cc(void)
-{
-    CC_SRC = cc_table[CC_OP].compute_c();
-    T0--;
     CC_DST = T0;
 }
 
@@ -408,6 +329,11 @@ void OPPROTO op_andl_T0_ffff(void)
     T0 = T0 & 0xffff;
 }
 
+void OPPROTO op_andl_T0_im(void)
+{
+    T0 = T0 & PARAM1;
+}
+
 void OPPROTO op_movl_T0_T1(void)
 {
     T0 = T1;
@@ -450,70 +376,14 @@ void OPPROTO op_andl_A0_ffff(void)
 
 /* memory access */
 
-void OPPROTO op_ldub_T0_A0(void)
-{
-    T0 = ldub((uint8_t *)A0);
-}
-
-void OPPROTO op_ldsb_T0_A0(void)
-{
-    T0 = ldsb((int8_t *)A0);
-}
-
-void OPPROTO op_lduw_T0_A0(void)
-{
-    T0 = lduw((uint8_t *)A0);
-}
-
-void OPPROTO op_ldsw_T0_A0(void)
-{
-    T0 = ldsw((int8_t *)A0);
-}
-
-void OPPROTO op_ldl_T0_A0(void)
-{
-    T0 = ldl((uint8_t *)A0);
-}
-
-void OPPROTO op_ldub_T1_A0(void)
-{
-    T1 = ldub((uint8_t *)A0);
-}
-
-void OPPROTO op_ldsb_T1_A0(void)
-{
-    T1 = ldsb((int8_t *)A0);
-}
-
-void OPPROTO op_lduw_T1_A0(void)
-{
-    T1 = lduw((uint8_t *)A0);
-}
-
-void OPPROTO op_ldsw_T1_A0(void)
-{
-    T1 = ldsw((int8_t *)A0);
-}
-
-void OPPROTO op_ldl_T1_A0(void)
-{
-    T1 = ldl((uint8_t *)A0);
-}
-
-void OPPROTO op_stb_T0_A0(void)
-{
-    stb((uint8_t *)A0, T0);
-}
+#define MEMSUFFIX
+#include "ops_mem.h"
 
-void OPPROTO op_stw_T0_A0(void)
-{
-    stw((uint8_t *)A0, T0);
-}
+#define MEMSUFFIX _user
+#include "ops_mem.h"
 
-void OPPROTO op_stl_T0_A0(void)
-{
-    stl((uint8_t *)A0, T0);
-}
+#define MEMSUFFIX _kernel
+#include "ops_mem.h"
 
 /* used for bit operations */
 
@@ -539,6 +409,18 @@ void OPPROTO op_jmp_im(void)
     EIP = PARAM1;
 }
 
+void OPPROTO op_hlt(void)
+{
+    env->exception_index = EXCP_HLT;
+    cpu_loop_exit();
+}
+
+void OPPROTO op_debug(void)
+{
+    env->exception_index = EXCP_DEBUG;
+    cpu_loop_exit();
+}
+
 void OPPROTO op_raise_interrupt(void)
 {
     int intno;
@@ -624,33 +506,6 @@ void OPPROTO op_cmpxchg8b(void)
     helper_cmpxchg8b();
 }
 
-#if defined(__powerpc__)
-
-/* on PowerPC we patch the jump instruction directly */
-#define JUMP_TB(tbparam, n, eip)\
-do {\
-    static void __attribute__((unused)) *__op_label ## n = &&label ## n;\
-    asm volatile ("b %0" : : "i" (&__op_jmp ## n));\
-label ## n:\
-    T0 = (long)(tbparam) + (n);\
-    EIP = eip;\
-} while (0)
-
-#else
-
-/* jump to next block operations (more portable code, does not need
-   cache flushing, but slower because of indirect jump) */
-#define JUMP_TB(tbparam, n, eip)\
-do {\
-    static void __attribute__((unused)) *__op_label ## n = &&label ## n;\
-    goto *(void *)(((TranslationBlock *)tbparam)->tb_next[n]);\
-label ## n:\
-    T0 = (long)(tbparam) + (n);\
-    EIP = eip;\
-} while (0)
-
-#endif
-
 void OPPROTO op_jmp_tb_next(void)
 {
     JUMP_TB(PARAM1, 0, PARAM2);
@@ -661,6 +516,11 @@ void OPPROTO op_movl_T0_0(void)
     T0 = 0;
 }
 
+void OPPROTO op_exit_tb(void)
+{
+    EXIT_TB();
+}
+
 /* multiple size ops */
 
 #define ldul ldl
@@ -719,6 +579,38 @@ void OPPROTO op_movswl_DX_AX(void)
     EDX = (EDX & 0xffff0000) | (((int16_t)EAX >> 15) & 0xffff);
 }
 
+/* string ops helpers */
+
+void OPPROTO op_addl_ESI_T0(void)
+{
+    ESI += T0;
+}
+
+void OPPROTO op_addw_ESI_T0(void)
+{
+    ESI = (ESI & ~0xffff) | ((ESI + T0) & 0xffff);
+}
+
+void OPPROTO op_addl_EDI_T0(void)
+{
+    EDI += T0;
+}
+
+void OPPROTO op_addw_EDI_T0(void)
+{
+    EDI = (EDI & ~0xffff) | ((EDI + T0) & 0xffff);
+}
+
+void OPPROTO op_decl_ECX(void)
+{
+    ECX--;
+}
+
+void OPPROTO op_decw_ECX(void)
+{
+    ECX = (ECX & ~0xffff) | ((ECX - 1) & 0xffff);
+}
+
 /* push/pop */
 
 void op_pushl_T0(void)
@@ -743,7 +635,7 @@ void op_pushl_ss32_T0(void)
 {
     uint32_t offset;
     offset = ESP - 4;
-    stl(env->seg_cache[R_SS].base + offset, T0);
+    stl(env->segs[R_SS].base + offset, T0);
     /* modify ESP after to handle exceptions correctly */
     ESP = offset;
 }
@@ -752,7 +644,7 @@ void op_pushw_ss32_T0(void)
 {
     uint32_t offset;
     offset = ESP - 2;
-    stw(env->seg_cache[R_SS].base + offset, T0);
+    stw(env->segs[R_SS].base + offset, T0);
     /* modify ESP after to handle exceptions correctly */
     ESP = offset;
 }
@@ -761,7 +653,7 @@ void op_pushl_ss16_T0(void)
 {
     uint32_t offset;
     offset = (ESP - 4) & 0xffff;
-    stl(env->seg_cache[R_SS].base + offset, T0);
+    stl(env->segs[R_SS].base + offset, T0);
     /* modify ESP after to handle exceptions correctly */
     ESP = (ESP & ~0xffff) | offset;
 }
@@ -770,7 +662,7 @@ void op_pushw_ss16_T0(void)
 {
     uint32_t offset;
     offset = (ESP - 2) & 0xffff;
-    stw(env->seg_cache[R_SS].base + offset, T0);
+    stw(env->segs[R_SS].base + offset, T0);
     /* modify ESP after to handle exceptions correctly */
     ESP = (ESP & ~0xffff) | offset;
 }
@@ -788,22 +680,22 @@ void op_popw_T0(void)
 
 void op_popl_ss32_T0(void)
 {
-    T0 = ldl(env->seg_cache[R_SS].base + ESP);
+    T0 = ldl(env->segs[R_SS].base + ESP);
 }
 
 void op_popw_ss32_T0(void)
 {
-    T0 = lduw(env->seg_cache[R_SS].base + ESP);
+    T0 = lduw(env->segs[R_SS].base + ESP);
 }
 
 void op_popl_ss16_T0(void)
 {
-    T0 = ldl(env->seg_cache[R_SS].base + (ESP & 0xffff));
+    T0 = ldl(env->segs[R_SS].base + (ESP & 0xffff));
 }
 
 void op_popw_ss16_T0(void)
 {
-    T0 = lduw(env->seg_cache[R_SS].base + (ESP & 0xffff));
+    T0 = lduw(env->segs[R_SS].base + (ESP & 0xffff));
 }
 
 void op_addl_ESP_4(void)
@@ -846,6 +738,16 @@ void OPPROTO op_cpuid(void)
     helper_cpuid();
 }
 
+void OPPROTO op_rdmsr(void)
+{
+    helper_rdmsr();
+}
+
+void OPPROTO op_wrmsr(void)
+{
+    helper_wrmsr();
+}
+
 /* bcd */
 
 /* XXX: exception */
@@ -987,17 +889,18 @@ void OPPROTO op_movl_seg_T0(void)
 void OPPROTO op_movl_seg_T0_vm(void)
 {
     int selector;
+    SegmentCache *sc;
     
     selector = T0 & 0xffff;
     /* env->segs[] access */
-    *(uint32_t *)((char *)env + PARAM1) = selector;
-    /* env->seg_cache[] access */
-    ((SegmentCache *)((char *)env + PARAM2))->base = (void *)(selector << 4);
+    sc = (SegmentCache *)((char *)env + PARAM1);
+    sc->selector = selector;
+    sc->base = (void *)(selector << 4);
 }
 
 void OPPROTO op_movl_T0_seg(void)
 {
-    T0 = env->segs[PARAM1];
+    T0 = env->segs[PARAM1].selector;
 }
 
 void OPPROTO op_movl_A0_seg(void)
@@ -1020,6 +923,91 @@ void OPPROTO op_lar(void)
     helper_lar();
 }
 
+/* T0: segment, T1:eip */
+void OPPROTO op_ljmp_protected_T0_T1(void)
+{
+    helper_ljmp_protected_T0_T1();
+}
+
+void OPPROTO op_lcall_real_T0_T1(void)
+{
+    helper_lcall_real_T0_T1(PARAM1, PARAM2);
+}
+
+void OPPROTO op_lcall_protected_T0_T1(void)
+{
+    helper_lcall_protected_T0_T1(PARAM1, PARAM2);
+}
+
+void OPPROTO op_iret_real(void)
+{
+    helper_iret_real(PARAM1);
+}
+
+void OPPROTO op_iret_protected(void)
+{
+    helper_iret_protected(PARAM1);
+}
+
+void OPPROTO op_lret_protected(void)
+{
+    helper_lret_protected(PARAM1, PARAM2);
+}
+
+void OPPROTO op_lldt_T0(void)
+{
+    helper_lldt_T0();
+}
+
+void OPPROTO op_ltr_T0(void)
+{
+    helper_ltr_T0();
+}
+
+/* CR registers access */
+void OPPROTO op_movl_crN_T0(void)
+{
+    helper_movl_crN_T0(PARAM1);
+}
+
+/* DR registers access */
+void OPPROTO op_movl_drN_T0(void)
+{
+    helper_movl_drN_T0(PARAM1);
+}
+
+void OPPROTO op_lmsw_T0(void)
+{
+    /* only 4 lower bits of CR0 are modified */
+    T0 = (env->cr[0] & ~0xf) | (T0 & 0xf);
+    helper_movl_crN_T0(0);
+}
+
+void OPPROTO op_invlpg_A0(void)
+{
+    helper_invlpg(A0);
+}
+
+void OPPROTO op_movl_T0_env(void)
+{
+    T0 = *(uint32_t *)((char *)env + PARAM1);
+}
+
+void OPPROTO op_movl_env_T0(void)
+{
+    *(uint32_t *)((char *)env + PARAM1) = T0;
+}
+
+void OPPROTO op_movl_env_T1(void)
+{
+    *(uint32_t *)((char *)env + PARAM1) = T1;
+}
+
+void OPPROTO op_clts(void)
+{
+    env->cr[0] &= ~CR0_TS_MASK;
+}
+
 /* flags handling */
 
 /* slow jumps cases : in order to avoid calling a function with a
@@ -1099,8 +1087,7 @@ void OPPROTO op_set_cc_op(void)
     CC_OP = PARAM1;
 }
 
-#define FL_UPDATE_MASK32 (TF_MASK | AC_MASK | ID_MASK)
-#define FL_UPDATE_MASK16 (TF_MASK)
+#define FL_UPDATE_MASK16 (FL_UPDATE_MASK32 & 0xffff)
 
 void OPPROTO op_movl_eflags_T0(void)
 {
@@ -1109,7 +1096,8 @@ void OPPROTO op_movl_eflags_T0(void)
     CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
     DF = 1 - (2 * ((eflags >> 10) & 1));
     /* we also update some system flags as in user mode */
-    env->eflags = (env->eflags & ~FL_UPDATE_MASK32) | (eflags & FL_UPDATE_MASK32);
+    env->eflags = (env->eflags & ~FL_UPDATE_MASK32) | 
+        (eflags & FL_UPDATE_MASK32);
 }
 
 void OPPROTO op_movw_eflags_T0(void)
@@ -1119,7 +1107,18 @@ void OPPROTO op_movw_eflags_T0(void)
     CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
     DF = 1 - (2 * ((eflags >> 10) & 1));
     /* we also update some system flags as in user mode */
-    env->eflags = (env->eflags & ~FL_UPDATE_MASK16) | (eflags & FL_UPDATE_MASK16);
+    env->eflags = (env->eflags & ~FL_UPDATE_MASK16) | 
+        (eflags & FL_UPDATE_MASK16);
+}
+
+void OPPROTO op_movl_eflags_T0_cpl0(void)
+{
+    load_eflags(T0, FL_UPDATE_CPL0_MASK);
+}
+
+void OPPROTO op_movw_eflags_T0_cpl0(void)
+{
+    load_eflags(T0, FL_UPDATE_CPL0_MASK & 0xffff);
 }
 
 #if 0
@@ -1424,28 +1423,40 @@ void OPPROTO op_fildll_FT0_A0(void)
 
 void OPPROTO op_flds_ST0_A0(void)
 {
+    int new_fpstt;
+    new_fpstt = (env->fpstt - 1) & 7;
 #ifdef USE_FP_CONVERT
     FP_CONVERT.i32 = ldl((void *)A0);
-    ST0 = FP_CONVERT.f;
+    env->fpregs[new_fpstt] = FP_CONVERT.f;
 #else
-    ST0 = ldfl((void *)A0);
+    env->fpregs[new_fpstt] = ldfl((void *)A0);
 #endif
+    env->fpstt = new_fpstt;
+    env->fptags[new_fpstt] = 0; /* validate stack entry */
 }
 
 void OPPROTO op_fldl_ST0_A0(void)
 {
+    int new_fpstt;
+    new_fpstt = (env->fpstt - 1) & 7;
 #ifdef USE_FP_CONVERT
     FP_CONVERT.i64 = ldq((void *)A0);
-    ST0 = FP_CONVERT.d;
+    env->fpregs[new_fpstt] = FP_CONVERT.d;
 #else
-    ST0 = ldfq((void *)A0);
+    env->fpregs[new_fpstt] = ldfq((void *)A0);
 #endif
+    env->fpstt = new_fpstt;
+    env->fptags[new_fpstt] = 0; /* validate stack entry */
 }
 
 #ifdef USE_X86LDOUBLE
 void OPPROTO op_fldt_ST0_A0(void)
 {
-    ST0 = *(long double *)A0;
+    int new_fpstt;
+    new_fpstt = (env->fpstt - 1) & 7;
+    env->fpregs[new_fpstt] = *(long double *)A0;
+    env->fpstt = new_fpstt;
+    env->fptags[new_fpstt] = 0; /* validate stack entry */
 }
 #else
 void OPPROTO op_fldt_ST0_A0(void)
@@ -1459,17 +1470,29 @@ void OPPROTO op_fldt_ST0_A0(void)
 
 void helper_fild_ST0_A0(void)
 {
-    ST0 = (CPU86_LDouble)ldsw((void *)A0);
+    int new_fpstt;
+    new_fpstt = (env->fpstt - 1) & 7;
+    env->fpregs[new_fpstt] = (CPU86_LDouble)ldsw((void *)A0);
+    env->fpstt = new_fpstt;
+    env->fptags[new_fpstt] = 0; /* validate stack entry */
 }
 
 void helper_fildl_ST0_A0(void)
 {
-    ST0 = (CPU86_LDouble)((int32_t)ldl((void *)A0));
+    int new_fpstt;
+    new_fpstt = (env->fpstt - 1) & 7;
+    env->fpregs[new_fpstt] = (CPU86_LDouble)((int32_t)ldl((void *)A0));
+    env->fpstt = new_fpstt;
+    env->fptags[new_fpstt] = 0; /* validate stack entry */
 }
 
 void helper_fildll_ST0_A0(void)
 {
-    ST0 = (CPU86_LDouble)((int64_t)ldq((void *)A0));
+    int new_fpstt;
+    new_fpstt = (env->fpstt - 1) & 7;
+    env->fpregs[new_fpstt] = (CPU86_LDouble)((int64_t)ldq((void *)A0));
+    env->fpstt = new_fpstt;
+    env->fptags[new_fpstt] = 0; /* validate stack entry */
 }
 
 void OPPROTO op_fild_ST0_A0(void)
@@ -1491,32 +1514,44 @@ void OPPROTO op_fildll_ST0_A0(void)
 
 void OPPROTO op_fild_ST0_A0(void)
 {
+    int new_fpstt;
+    new_fpstt = (env->fpstt - 1) & 7;
 #ifdef USE_FP_CONVERT
     FP_CONVERT.i32 = ldsw((void *)A0);
-    ST0 = (CPU86_LDouble)FP_CONVERT.i32;
+    env->fpregs[new_fpstt] = (CPU86_LDouble)FP_CONVERT.i32;
 #else
-    ST0 = (CPU86_LDouble)ldsw((void *)A0);
+    env->fpregs[new_fpstt] = (CPU86_LDouble)ldsw((void *)A0);
 #endif
+    env->fpstt = new_fpstt;
+    env->fptags[new_fpstt] = 0; /* validate stack entry */
 }
 
 void OPPROTO op_fildl_ST0_A0(void)
 {
+    int new_fpstt;
+    new_fpstt = (env->fpstt - 1) & 7;
 #ifdef USE_FP_CONVERT
     FP_CONVERT.i32 = (int32_t) ldl((void *)A0);
-    ST0 = (CPU86_LDouble)FP_CONVERT.i32;
+    env->fpregs[new_fpstt] = (CPU86_LDouble)FP_CONVERT.i32;
 #else
-    ST0 = (CPU86_LDouble)((int32_t)ldl((void *)A0));
+    env->fpregs[new_fpstt] = (CPU86_LDouble)((int32_t)ldl((void *)A0));
 #endif
+    env->fpstt = new_fpstt;
+    env->fptags[new_fpstt] = 0; /* validate stack entry */
 }
 
 void OPPROTO op_fildll_ST0_A0(void)
 {
+    int new_fpstt;
+    new_fpstt = (env->fpstt - 1) & 7;
 #ifdef USE_FP_CONVERT
     FP_CONVERT.i64 = (int64_t) ldq((void *)A0);
-    ST0 = (CPU86_LDouble)FP_CONVERT.i64;
+    env->fpregs[new_fpstt] = (CPU86_LDouble)FP_CONVERT.i64;
 #else
-    ST0 = (CPU86_LDouble)((int64_t)ldq((void *)A0));
+    env->fpregs[new_fpstt] = (CPU86_LDouble)((int64_t)ldq((void *)A0));
 #endif
+    env->fpstt = new_fpstt;
+    env->fptags[new_fpstt] = 0; /* validate stack entry */
 }
 
 #endif
@@ -1561,6 +1596,8 @@ void OPPROTO op_fist_ST0_A0(void)
 
     d = ST0;
     val = lrint(d);
+    if (val != (int16_t)val)
+        val = -32768;
     stw((void *)A0, val);
 }
 
This page took 0.041573 seconds and 4 git commands to generate.