提交 4d40895f 编写于 作者: B bellard

more accurate bcd convert - fixed FPU exceptions


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@304 c046a42c-6fe2-441c-8c8c-71466251a162
上级 e477b8b8
...@@ -981,7 +981,11 @@ void helper_lar(void) ...@@ -981,7 +981,11 @@ void helper_lar(void)
#ifndef USE_X86LDOUBLE #ifndef USE_X86LDOUBLE
void helper_fldt_ST0_A0(void) void helper_fldt_ST0_A0(void)
{ {
ST0 = helper_fldt((uint8_t *)A0); int new_fpstt;
new_fpstt = (env->fpstt - 1) & 7;
env->fpregs[new_fpstt] = helper_fldt((uint8_t *)A0);
env->fpstt = new_fpstt;
env->fptags[new_fpstt] = 0; /* validate stack entry */
} }
void helper_fstt_ST0_A0(void) 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)
void helper_fbld_ST0_A0(void) void helper_fbld_ST0_A0(void)
{ {
uint8_t *seg; CPU86_LDouble tmp;
CPU86_LDouble fpsrcop; uint64_t val;
int m32i;
unsigned int v; unsigned int v;
int i;
/* in this code, seg/m32i will be used as temporary ptr/int */ val = 0;
seg = (uint8_t *)A0 + 8; for(i = 8; i >= 0; i--) {
v = ldub(seg--); v = ldub((uint8_t *)A0 + i);
/* XXX: raise exception */ val = (val * 100) + ((v >> 4) * 10) + (v & 0xf);
if (v != 0) }
return; tmp = val;
v = ldub(seg--); if (ldub((uint8_t *)A0 + 9) & 0x80)
/* XXX: raise exception */ tmp = -tmp;
if ((v & 0xf0) != 0) fpush();
return; ST0 = tmp;
m32i = v; /* <-- d14 */
v = ldub(seg--);
m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d13 */
m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d12 */
v = ldub(seg--);
m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d11 */
m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d10 */
v = ldub(seg--);
m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d9 */
m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d8 */
fpsrcop = ((CPU86_LDouble)m32i) * 100000000.0;
v = ldub(seg--);
m32i = (v >> 4); /* <-- d7 */
m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d6 */
v = ldub(seg--);
m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d5 */
m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d4 */
v = ldub(seg--);
m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d3 */
m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d2 */
v = ldub(seg);
m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d1 */
m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d0 */
fpsrcop += ((CPU86_LDouble)m32i);
if ( ldub(seg+9) & 0x80 )
fpsrcop = -fpsrcop;
ST0 = fpsrcop;
} }
void helper_fbst_ST0_A0(void) void helper_fbst_ST0_A0(void)
{ {
CPU86_LDouble fptemp; CPU86_LDouble tmp;
CPU86_LDouble fpsrcop;
int v; int v;
uint8_t *mem_ref, *mem_end; uint8_t *mem_ref, *mem_end;
int64_t val;
fpsrcop = rint(ST0); tmp = rint(ST0);
val = (int64_t)tmp;
mem_ref = (uint8_t *)A0; mem_ref = (uint8_t *)A0;
mem_end = mem_ref + 8; mem_end = mem_ref + 9;
if ( fpsrcop < 0.0 ) { if (val < 0) {
stw(mem_end, 0x8000); stb(mem_end, 0x80);
fpsrcop = -fpsrcop; val = -val;
} else { } else {
stw(mem_end, 0x0000); stb(mem_end, 0x00);
} }
while (mem_ref < mem_end) { while (mem_ref < mem_end) {
if (fpsrcop == 0.0) if (val == 0)
break; break;
fptemp = floor(fpsrcop/10.0); v = val % 100;
v = ((int)(fpsrcop - fptemp*10.0)); val = val / 100;
if (fptemp == 0.0) { v = ((v / 10) << 4) | (v % 10);
stb(mem_ref++, v);
break;
}
fpsrcop = fptemp;
fptemp = floor(fpsrcop/10.0);
v |= (((int)(fpsrcop - fptemp*10.0)) << 4);
stb(mem_ref++, v); stb(mem_ref++, v);
fpsrcop = fptemp;
} }
while (mem_ref < mem_end) { while (mem_ref < mem_end) {
stb(mem_ref++, 0); stb(mem_ref++, 0);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册