mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 13:05:28 +00:00
target-i386: exception handling for div instructions
This patch fixes exception handling for div instructions and removes obsolete PC update from translate.c. Backports commit cc33c5d66bb315f77739f761a3f868a7d138c041 from qemu
This commit is contained in:
parent
afe5ed6f49
commit
837a36b1e8
|
@ -48,11 +48,11 @@ void helper_divb_AL(CPUX86State *env, target_ulong t0)
|
|||
num = (env->regs[R_EAX] & 0xffff);
|
||||
den = (t0 & 0xff);
|
||||
if (den == 0) {
|
||||
raise_exception(env, EXCP00_DIVZ);
|
||||
raise_exception_ra(env, EXCP00_DIVZ, GETPC());
|
||||
}
|
||||
q = (num / den);
|
||||
if (q > 0xff) {
|
||||
raise_exception(env, EXCP00_DIVZ);
|
||||
raise_exception_ra(env, EXCP00_DIVZ, GETPC());
|
||||
}
|
||||
q &= 0xff;
|
||||
r = (num % den) & 0xff;
|
||||
|
@ -66,11 +66,11 @@ void helper_idivb_AL(CPUX86State *env, target_ulong t0)
|
|||
num = (int16_t)env->regs[R_EAX];
|
||||
den = (int8_t)t0;
|
||||
if (den == 0) {
|
||||
raise_exception(env, EXCP00_DIVZ);
|
||||
raise_exception_ra(env, EXCP00_DIVZ, GETPC());
|
||||
}
|
||||
q = (num / den);
|
||||
if (q != (int8_t)q) {
|
||||
raise_exception(env, EXCP00_DIVZ);
|
||||
raise_exception_ra(env, EXCP00_DIVZ, GETPC());
|
||||
}
|
||||
q &= 0xff;
|
||||
r = (num % den) & 0xff;
|
||||
|
@ -84,11 +84,11 @@ void helper_divw_AX(CPUX86State *env, target_ulong t0)
|
|||
num = (env->regs[R_EAX] & 0xffff) | ((env->regs[R_EDX] & 0xffff) << 16);
|
||||
den = (t0 & 0xffff);
|
||||
if (den == 0) {
|
||||
raise_exception(env, EXCP00_DIVZ);
|
||||
raise_exception_ra(env, EXCP00_DIVZ, GETPC());
|
||||
}
|
||||
q = (num / den);
|
||||
if (q > 0xffff) {
|
||||
raise_exception(env, EXCP00_DIVZ);
|
||||
raise_exception_ra(env, EXCP00_DIVZ, GETPC());
|
||||
}
|
||||
q &= 0xffff;
|
||||
r = (num % den) & 0xffff;
|
||||
|
@ -103,11 +103,11 @@ void helper_idivw_AX(CPUX86State *env, target_ulong t0)
|
|||
num = (env->regs[R_EAX] & 0xffff) | ((env->regs[R_EDX] & 0xffff) << 16);
|
||||
den = (int16_t)t0;
|
||||
if (den == 0) {
|
||||
raise_exception(env, EXCP00_DIVZ);
|
||||
raise_exception_ra(env, EXCP00_DIVZ, GETPC());
|
||||
}
|
||||
q = (num / den);
|
||||
if (q != (int16_t)q) {
|
||||
raise_exception(env, EXCP00_DIVZ);
|
||||
raise_exception_ra(env, EXCP00_DIVZ, GETPC());
|
||||
}
|
||||
q &= 0xffff;
|
||||
r = (num % den) & 0xffff;
|
||||
|
@ -123,12 +123,12 @@ void helper_divl_EAX(CPUX86State *env, target_ulong t0)
|
|||
num = ((uint32_t)env->regs[R_EAX]) | ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32);
|
||||
den = (unsigned int)t0;
|
||||
if (den == 0) {
|
||||
raise_exception(env, EXCP00_DIVZ);
|
||||
raise_exception_ra(env, EXCP00_DIVZ, GETPC());
|
||||
}
|
||||
q = (num / den);
|
||||
r = (num % den);
|
||||
if (q > 0xffffffff) {
|
||||
raise_exception(env, EXCP00_DIVZ);
|
||||
raise_exception_ra(env, EXCP00_DIVZ, GETPC());
|
||||
}
|
||||
env->regs[R_EAX] = (uint32_t)q;
|
||||
env->regs[R_EDX] = (uint32_t)r;
|
||||
|
@ -142,12 +142,12 @@ void helper_idivl_EAX(CPUX86State *env, target_ulong t0)
|
|||
num = ((uint32_t)env->regs[R_EAX]) | ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32);
|
||||
den = (int)t0;
|
||||
if (den == 0) {
|
||||
raise_exception(env, EXCP00_DIVZ);
|
||||
raise_exception_ra(env, EXCP00_DIVZ, GETPC());
|
||||
}
|
||||
q = (num / den);
|
||||
r = (num % den);
|
||||
if (q != (int32_t)q) {
|
||||
raise_exception(env, EXCP00_DIVZ);
|
||||
raise_exception_ra(env, EXCP00_DIVZ, GETPC());
|
||||
}
|
||||
env->regs[R_EAX] = (uint32_t)q;
|
||||
env->regs[R_EDX] = (uint32_t)r;
|
||||
|
@ -379,12 +379,12 @@ void helper_divq_EAX(CPUX86State *env, target_ulong t0)
|
|||
uint64_t r0, r1;
|
||||
|
||||
if (t0 == 0) {
|
||||
raise_exception(env, EXCP00_DIVZ);
|
||||
raise_exception_ra(env, EXCP00_DIVZ, GETPC());
|
||||
}
|
||||
r0 = env->regs[R_EAX];
|
||||
r1 = env->regs[R_EDX];
|
||||
if (div64(&r0, &r1, t0)) {
|
||||
raise_exception(env, EXCP00_DIVZ);
|
||||
raise_exception_ra(env, EXCP00_DIVZ, GETPC());
|
||||
}
|
||||
env->regs[R_EAX] = r0;
|
||||
env->regs[R_EDX] = r1;
|
||||
|
@ -395,12 +395,12 @@ void helper_idivq_EAX(CPUX86State *env, target_ulong t0)
|
|||
uint64_t r0, r1;
|
||||
|
||||
if (t0 == 0) {
|
||||
raise_exception(env, EXCP00_DIVZ);
|
||||
raise_exception_ra(env, EXCP00_DIVZ, GETPC());
|
||||
}
|
||||
r0 = env->regs[R_EAX];
|
||||
r1 = env->regs[R_EDX];
|
||||
if (idiv64(&r0, &r1, t0)) {
|
||||
raise_exception(env, EXCP00_DIVZ);
|
||||
raise_exception_ra(env, EXCP00_DIVZ, GETPC());
|
||||
}
|
||||
env->regs[R_EAX] = r0;
|
||||
env->regs[R_EDX] = r1;
|
||||
|
|
|
@ -5475,21 +5475,17 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
|
|||
case 6: /* div */
|
||||
switch(ot) {
|
||||
case MO_8:
|
||||
gen_jmp_im(s, pc_start - s->cs_base);
|
||||
gen_helper_divb_AL(tcg_ctx, cpu_env, *cpu_T[0]);
|
||||
break;
|
||||
case MO_16:
|
||||
gen_jmp_im(s, pc_start - s->cs_base);
|
||||
gen_helper_divw_AX(tcg_ctx, cpu_env, *cpu_T[0]);
|
||||
break;
|
||||
default:
|
||||
case MO_32:
|
||||
gen_jmp_im(s, pc_start - s->cs_base);
|
||||
gen_helper_divl_EAX(tcg_ctx, cpu_env, *cpu_T[0]);
|
||||
break;
|
||||
#ifdef TARGET_X86_64
|
||||
case MO_64:
|
||||
gen_jmp_im(s, pc_start - s->cs_base);
|
||||
gen_helper_divq_EAX(tcg_ctx, cpu_env, *cpu_T[0]);
|
||||
break;
|
||||
#endif
|
||||
|
@ -5498,21 +5494,17 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
|
|||
case 7: /* idiv */
|
||||
switch(ot) {
|
||||
case MO_8:
|
||||
gen_jmp_im(s, pc_start - s->cs_base);
|
||||
gen_helper_idivb_AL(tcg_ctx, cpu_env, *cpu_T[0]);
|
||||
break;
|
||||
case MO_16:
|
||||
gen_jmp_im(s, pc_start - s->cs_base);
|
||||
gen_helper_idivw_AX(tcg_ctx, cpu_env, *cpu_T[0]);
|
||||
break;
|
||||
default:
|
||||
case MO_32:
|
||||
gen_jmp_im(s, pc_start - s->cs_base);
|
||||
gen_helper_idivl_EAX(tcg_ctx, cpu_env, *cpu_T[0]);
|
||||
break;
|
||||
#ifdef TARGET_X86_64
|
||||
case MO_64:
|
||||
gen_jmp_im(s, pc_start - s->cs_base);
|
||||
gen_helper_idivq_EAX(tcg_ctx, cpu_env, *cpu_T[0]);
|
||||
break;
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue