div64 fix - raise_interrupt() fix - SSE fix

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1202 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
bellard 2005-01-06 20:46:58 +00:00
parent 826461bb40
commit a8ede8ba8b
5 changed files with 23 additions and 28 deletions

View file

@ -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);

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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;