diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2005-01-06 20:46:58 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2005-01-06 20:46:58 +0000 |
commit | a8ede8ba8be076ae56b7c9ce9b4f2a115589543a (patch) | |
tree | 27891967931c9729b5ec3bc8dd5381d985db5a63 /target-i386 | |
parent | 826461bb4068bab1c8fef6eb11117a260aa3e2c0 (diff) |
div64 fix - raise_interrupt() fix - SSE fix
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1202 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-i386')
-rw-r--r-- | target-i386/exec.h | 6 | ||||
-rw-r--r-- | target-i386/helper.c | 21 | ||||
-rw-r--r-- | target-i386/op.c | 7 | ||||
-rw-r--r-- | target-i386/ops_mem.h | 10 | ||||
-rw-r--r-- | target-i386/translate.c | 7 |
5 files changed, 23 insertions, 28 deletions
diff --git a/target-i386/exec.h b/target-i386/exec.h index 5529c35524..330343164a 100644 --- a/target-i386/exec.h +++ b/target-i386/exec.h @@ -176,17 +176,13 @@ void do_interrupt(int intno, int is_int, int error_code, void do_interrupt_user(int intno, int is_int, int error_code, target_ulong next_eip); void raise_interrupt(int intno, int is_int, int error_code, - unsigned int next_eip); + int next_eip_addend); void raise_exception_err(int exception_index, int error_code); void raise_exception(int exception_index); void __hidden cpu_loop_exit(void); void OPPROTO op_movl_eflags_T0(void); void OPPROTO op_movl_T0_eflags(void); -void raise_interrupt(int intno, int is_int, int error_code, - unsigned int next_eip); -void raise_exception_err(int exception_index, int error_code); -void raise_exception(int exception_index); void helper_divl_EAX_T0(void); void helper_idivl_EAX_T0(void); void helper_mulq_EAX_T0(void); diff --git a/target-i386/helper.c b/target-i386/helper.c index 64d6f9e7ad..2567657a7f 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -1157,12 +1157,12 @@ void do_interrupt(int intno, int is_int, int error_code, * is_int is TRUE. */ void raise_interrupt(int intno, int is_int, int error_code, - unsigned int next_eip) + int next_eip_addend) { env->exception_index = intno; env->error_code = error_code; env->exception_is_int = is_int; - env->exception_next_eip = next_eip; + env->exception_next_eip = env->eip + next_eip_addend; cpu_loop_exit(); } @@ -2929,14 +2929,14 @@ void helper_fxsave(target_ulong ptr, int data64) } if (env->cr[4] & CR4_OSFXSR_MASK) { - /* XXX: finish it, endianness */ + /* XXX: finish it */ stl(ptr + 0x18, 0); /* mxcsr */ stl(ptr + 0x1c, 0); /* mxcsr_mask */ nb_xmm_regs = 8 << data64; addr = ptr + 0xa0; for(i = 0; i < nb_xmm_regs; i++) { - stq(addr, env->xmm_regs[i].u.q[0]); - stq(addr, env->xmm_regs[i].u.q[1]); + stq(addr, env->xmm_regs[i].XMM_Q(0)); + stq(addr + 8, env->xmm_regs[i].XMM_Q(1)); addr += 16; } } @@ -2972,8 +2972,8 @@ void helper_fxrstor(target_ulong ptr, int data64) nb_xmm_regs = 8 << data64; addr = ptr + 0xa0; for(i = 0; i < nb_xmm_regs; i++) { - env->xmm_regs[i].u.q[0] = ldq(addr); - env->xmm_regs[i].u.q[1] = ldq(addr); + env->xmm_regs[i].XMM_Q(0) = ldq(addr); + env->xmm_regs[i].XMM_Q(1) = ldq(addr + 8); addr += 16; } } @@ -3099,6 +3099,7 @@ static void imul64(uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b) } } +/* XXX: overflow support */ static void div64(uint64_t *plow, uint64_t *phigh, uint64_t b) { uint64_t q, r, a1, a0; @@ -3114,16 +3115,16 @@ static void div64(uint64_t *plow, uint64_t *phigh, uint64_t b) } else { /* XXX: use a better algorithm */ for(i = 0; i < 64; i++) { + a1 = (a1 << 1) | (a0 >> 63); if (a1 >= b) { a1 -= b; qb = 1; } else { qb = 0; } - a1 = (a1 << 1) | (a0 >> 63); a0 = (a0 << 1) | qb; } -#if defined(DEBUG_MULDIV) || 1 +#if defined(DEBUG_MULDIV) printf("div: 0x%016llx%016llx / 0x%016llx: q=0x%016llx r=0x%016llx\n", *phigh, *plow, b, a0, a1); #endif @@ -3167,7 +3168,7 @@ void helper_imulq_EAX_T0(void) EAX = r0; EDX = r1; CC_DST = r0; - CC_SRC = (r1 != (r0 >> 63)); + CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63)); } void helper_imulq_T0_T1(void) diff --git a/target-i386/op.c b/target-i386/op.c index f81d59b161..9ce2a5a2b7 100644 --- a/target-i386/op.c +++ b/target-i386/op.c @@ -611,11 +611,10 @@ void OPPROTO op_debug(void) void OPPROTO op_raise_interrupt(void) { - int intno; - unsigned int next_eip; + int intno, next_eip_addend; intno = PARAM1; - next_eip = PARAM2; - raise_interrupt(intno, 1, 0, next_eip); + next_eip_addend = PARAM2; + raise_interrupt(intno, 1, 0, next_eip_addend); } void OPPROTO op_raise_exception(void) diff --git a/target-i386/ops_mem.h b/target-i386/ops_mem.h index 284ab71af4..21c17008b9 100644 --- a/target-i386/ops_mem.h +++ b/target-i386/ops_mem.h @@ -85,18 +85,16 @@ void OPPROTO glue(glue(op_ldo, MEMSUFFIX), _env_A0)(void) { XMMReg *p; p = (XMMReg *)((char *)env + PARAM1); - /* XXX: host endianness ? */ - p->u.q[0] = glue(ldq, MEMSUFFIX)(A0); - p->u.q[1] = glue(ldq, MEMSUFFIX)(A0 + 8); + p->XMM_Q(0) = glue(ldq, MEMSUFFIX)(A0); + p->XMM_Q(1) = glue(ldq, MEMSUFFIX)(A0 + 8); } void OPPROTO glue(glue(op_sto, MEMSUFFIX), _env_A0)(void) { XMMReg *p; p = (XMMReg *)((char *)env + PARAM1); - /* XXX: host endianness ? */ - glue(stq, MEMSUFFIX)(A0, p->u.q[0]); - glue(stq, MEMSUFFIX)(A0 + 8, p->u.q[1]); + glue(stq, MEMSUFFIX)(A0, p->XMM_Q(0)); + glue(stq, MEMSUFFIX)(A0 + 8, p->XMM_Q(1)); } #ifdef TARGET_X86_64 diff --git a/target-i386/translate.c b/target-i386/translate.c index 743aff7653..686c184f15 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -2119,7 +2119,7 @@ static void gen_interrupt(DisasContext *s, int intno, if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); gen_jmp_im(cur_eip); - gen_op_raise_interrupt(intno, next_eip); + gen_op_raise_interrupt(intno, (int)(next_eip - cur_eip)); s->is_jmp = 3; } @@ -4452,7 +4452,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) goto illegal_op; if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); - gen_op_into(s->pc - s->cs_base); + gen_jmp_im(pc_start - s->cs_base); + gen_op_into(s->pc - pc_start); break; case 0xf1: /* icebp (undocumented, exits to external debugger) */ #if 0 @@ -4826,7 +4827,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) /* nothing to do */ } break; - case 0x1ae: /* sfence */ + case 0x1ae: modrm = ldub_code(s->pc++); mod = (modrm >> 6) & 3; op = (modrm >> 3) & 7; |