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 | 981 | #ifndef USE_X86LDOUBLE |
982 | 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 | 991 | void helper_fstt_ST0_A0(void) |
... | ... | @@ -996,81 +1000,47 @@ void helper_fstt_ST0_A0(void) |
996 | 1000 | |
997 | 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 | 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 | 1020 | void helper_fbst_ST0_A0(void) |
1045 | 1021 | { |
1046 | - CPU86_LDouble fptemp; | |
1047 | - CPU86_LDouble fpsrcop; | |
1022 | + CPU86_LDouble tmp; | |
1048 | 1023 | int v; |
1049 | 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 | 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 | 1034 | } else { |
1058 | - stw(mem_end, 0x0000); | |
1035 | + stb(mem_end, 0x00); | |
1059 | 1036 | } |
1060 | 1037 | while (mem_ref < mem_end) { |
1061 | - if (fpsrcop == 0.0) | |
1038 | + if (val == 0) | |
1062 | 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 | 1043 | stb(mem_ref++, v); |
1073 | - fpsrcop = fptemp; | |
1074 | 1044 | } |
1075 | 1045 | while (mem_ref < mem_end) { |
1076 | 1046 | stb(mem_ref++, 0); | ... | ... |