Commit 4d40895f2c30354c48ad9181e366e8d738f9b4d7
1 parent
e477b8b8
more accurate bcd convert - fixed FPU exceptions
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@304 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
31 additions
and
61 deletions
helper-i386.c
| @@ -981,7 +981,11 @@ void helper_lar(void) | @@ -981,7 +981,11 @@ void helper_lar(void) | ||
| 981 | #ifndef USE_X86LDOUBLE | 981 | #ifndef USE_X86LDOUBLE |
| 982 | void helper_fldt_ST0_A0(void) | 982 | void helper_fldt_ST0_A0(void) |
| 983 | { | 983 | { |
| 984 | - ST0 = helper_fldt((uint8_t *)A0); | 984 | + int new_fpstt; |
| 985 | + new_fpstt = (env->fpstt - 1) & 7; | ||
| 986 | + env->fpregs[new_fpstt] = helper_fldt((uint8_t *)A0); | ||
| 987 | + env->fpstt = new_fpstt; | ||
| 988 | + env->fptags[new_fpstt] = 0; /* validate stack entry */ | ||
| 985 | } | 989 | } |
| 986 | 990 | ||
| 987 | void helper_fstt_ST0_A0(void) | 991 | void helper_fstt_ST0_A0(void) |
| @@ -996,81 +1000,47 @@ void helper_fstt_ST0_A0(void) | @@ -996,81 +1000,47 @@ void helper_fstt_ST0_A0(void) | ||
| 996 | 1000 | ||
| 997 | void helper_fbld_ST0_A0(void) | 1001 | void helper_fbld_ST0_A0(void) |
| 998 | { | 1002 | { |
| 999 | - uint8_t *seg; | ||
| 1000 | - CPU86_LDouble fpsrcop; | ||
| 1001 | - int m32i; | 1003 | + CPU86_LDouble tmp; |
| 1004 | + uint64_t val; | ||
| 1002 | unsigned int v; | 1005 | unsigned int v; |
| 1006 | + int i; | ||
| 1003 | 1007 | ||
| 1004 | - /* in this code, seg/m32i will be used as temporary ptr/int */ | ||
| 1005 | - seg = (uint8_t *)A0 + 8; | ||
| 1006 | - v = ldub(seg--); | ||
| 1007 | - /* XXX: raise exception */ | ||
| 1008 | - if (v != 0) | ||
| 1009 | - return; | ||
| 1010 | - v = ldub(seg--); | ||
| 1011 | - /* XXX: raise exception */ | ||
| 1012 | - if ((v & 0xf0) != 0) | ||
| 1013 | - return; | ||
| 1014 | - m32i = v; /* <-- d14 */ | ||
| 1015 | - v = ldub(seg--); | ||
| 1016 | - m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d13 */ | ||
| 1017 | - m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d12 */ | ||
| 1018 | - v = ldub(seg--); | ||
| 1019 | - m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d11 */ | ||
| 1020 | - m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d10 */ | ||
| 1021 | - v = ldub(seg--); | ||
| 1022 | - m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d9 */ | ||
| 1023 | - m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d8 */ | ||
| 1024 | - fpsrcop = ((CPU86_LDouble)m32i) * 100000000.0; | ||
| 1025 | - | ||
| 1026 | - v = ldub(seg--); | ||
| 1027 | - m32i = (v >> 4); /* <-- d7 */ | ||
| 1028 | - m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d6 */ | ||
| 1029 | - v = ldub(seg--); | ||
| 1030 | - m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d5 */ | ||
| 1031 | - m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d4 */ | ||
| 1032 | - v = ldub(seg--); | ||
| 1033 | - m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d3 */ | ||
| 1034 | - m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d2 */ | ||
| 1035 | - v = ldub(seg); | ||
| 1036 | - m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d1 */ | ||
| 1037 | - m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d0 */ | ||
| 1038 | - fpsrcop += ((CPU86_LDouble)m32i); | ||
| 1039 | - if ( ldub(seg+9) & 0x80 ) | ||
| 1040 | - fpsrcop = -fpsrcop; | ||
| 1041 | - ST0 = fpsrcop; | 1008 | + val = 0; |
| 1009 | + for(i = 8; i >= 0; i--) { | ||
| 1010 | + v = ldub((uint8_t *)A0 + i); | ||
| 1011 | + val = (val * 100) + ((v >> 4) * 10) + (v & 0xf); | ||
| 1012 | + } | ||
| 1013 | + tmp = val; | ||
| 1014 | + if (ldub((uint8_t *)A0 + 9) & 0x80) | ||
| 1015 | + tmp = -tmp; | ||
| 1016 | + fpush(); | ||
| 1017 | + ST0 = tmp; | ||
| 1042 | } | 1018 | } |
| 1043 | 1019 | ||
| 1044 | void helper_fbst_ST0_A0(void) | 1020 | void helper_fbst_ST0_A0(void) |
| 1045 | { | 1021 | { |
| 1046 | - CPU86_LDouble fptemp; | ||
| 1047 | - CPU86_LDouble fpsrcop; | 1022 | + CPU86_LDouble tmp; |
| 1048 | int v; | 1023 | int v; |
| 1049 | uint8_t *mem_ref, *mem_end; | 1024 | uint8_t *mem_ref, *mem_end; |
| 1025 | + int64_t val; | ||
| 1050 | 1026 | ||
| 1051 | - fpsrcop = rint(ST0); | 1027 | + tmp = rint(ST0); |
| 1028 | + val = (int64_t)tmp; | ||
| 1052 | mem_ref = (uint8_t *)A0; | 1029 | mem_ref = (uint8_t *)A0; |
| 1053 | - mem_end = mem_ref + 8; | ||
| 1054 | - if ( fpsrcop < 0.0 ) { | ||
| 1055 | - stw(mem_end, 0x8000); | ||
| 1056 | - fpsrcop = -fpsrcop; | 1030 | + mem_end = mem_ref + 9; |
| 1031 | + if (val < 0) { | ||
| 1032 | + stb(mem_end, 0x80); | ||
| 1033 | + val = -val; | ||
| 1057 | } else { | 1034 | } else { |
| 1058 | - stw(mem_end, 0x0000); | 1035 | + stb(mem_end, 0x00); |
| 1059 | } | 1036 | } |
| 1060 | while (mem_ref < mem_end) { | 1037 | while (mem_ref < mem_end) { |
| 1061 | - if (fpsrcop == 0.0) | 1038 | + if (val == 0) |
| 1062 | break; | 1039 | break; |
| 1063 | - fptemp = floor(fpsrcop/10.0); | ||
| 1064 | - v = ((int)(fpsrcop - fptemp*10.0)); | ||
| 1065 | - if (fptemp == 0.0) { | ||
| 1066 | - stb(mem_ref++, v); | ||
| 1067 | - break; | ||
| 1068 | - } | ||
| 1069 | - fpsrcop = fptemp; | ||
| 1070 | - fptemp = floor(fpsrcop/10.0); | ||
| 1071 | - v |= (((int)(fpsrcop - fptemp*10.0)) << 4); | 1040 | + v = val % 100; |
| 1041 | + val = val / 100; | ||
| 1042 | + v = ((v / 10) << 4) | (v % 10); | ||
| 1072 | stb(mem_ref++, v); | 1043 | stb(mem_ref++, v); |
| 1073 | - fpsrcop = fptemp; | ||
| 1074 | } | 1044 | } |
| 1075 | while (mem_ref < mem_end) { | 1045 | while (mem_ref < mem_end) { |
| 1076 | stb(mem_ref++, 0); | 1046 | stb(mem_ref++, 0); |