aboutsummaryrefslogtreecommitdiff
path: root/target/m68k/op_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/m68k/op_helper.c')
-rw-r--r--target/m68k/op_helper.c48
1 files changed, 29 insertions, 19 deletions
diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index 750d655..729ee0e 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -396,7 +396,6 @@ static void m68k_interrupt_all(CPUM68KState *env, int is_hw)
break;
case EXCP_ILLEGAL:
- case EXCP_DIV0:
case EXCP_TRAPCC:
case EXCP_TRACE:
/* FIXME: addr is not only env->pc */
@@ -404,6 +403,7 @@ static void m68k_interrupt_all(CPUM68KState *env, int is_hw)
break;
case EXCP_CHK:
+ case EXCP_DIV0:
do_stack_frame(env, &sp, 2, oldsr, env->mmu.ar, env->pc);
break;
@@ -574,18 +574,19 @@ raise_exception_format2(CPUM68KState *env, int tt, int ilen, uintptr_t raddr)
cpu_loop_exit(cs);
}
-void HELPER(divuw)(CPUM68KState *env, int destr, uint32_t den)
+void HELPER(divuw)(CPUM68KState *env, int destr, uint32_t den, int ilen)
{
uint32_t num = env->dregs[destr];
uint32_t quot, rem;
+ env->cc_c = 0; /* always cleared, even if div0 */
+
if (den == 0) {
- raise_exception_ra(env, EXCP_DIV0, GETPC());
+ raise_exception_format2(env, EXCP_DIV0, ilen, GETPC());
}
quot = num / den;
rem = num % den;
- env->cc_c = 0; /* always cleared, even if overflow */
if (quot > 0xffff) {
env->cc_v = -1;
/*
@@ -601,18 +602,19 @@ void HELPER(divuw)(CPUM68KState *env, int destr, uint32_t den)
env->cc_v = 0;
}
-void HELPER(divsw)(CPUM68KState *env, int destr, int32_t den)
+void HELPER(divsw)(CPUM68KState *env, int destr, int32_t den, int ilen)
{
int32_t num = env->dregs[destr];
uint32_t quot, rem;
+ env->cc_c = 0; /* always cleared, even if overflow/div0 */
+
if (den == 0) {
- raise_exception_ra(env, EXCP_DIV0, GETPC());
+ raise_exception_format2(env, EXCP_DIV0, ilen, GETPC());
}
quot = num / den;
rem = num % den;
- env->cc_c = 0; /* always cleared, even if overflow */
if (quot != (int16_t)quot) {
env->cc_v = -1;
/* nothing else is modified */
@@ -629,18 +631,20 @@ void HELPER(divsw)(CPUM68KState *env, int destr, int32_t den)
env->cc_v = 0;
}
-void HELPER(divul)(CPUM68KState *env, int numr, int regr, uint32_t den)
+void HELPER(divul)(CPUM68KState *env, int numr, int regr,
+ uint32_t den, int ilen)
{
uint32_t num = env->dregs[numr];
uint32_t quot, rem;
+ env->cc_c = 0; /* always cleared, even if div0 */
+
if (den == 0) {
- raise_exception_ra(env, EXCP_DIV0, GETPC());
+ raise_exception_format2(env, EXCP_DIV0, ilen, GETPC());
}
quot = num / den;
rem = num % den;
- env->cc_c = 0;
env->cc_z = quot;
env->cc_n = quot;
env->cc_v = 0;
@@ -657,18 +661,20 @@ void HELPER(divul)(CPUM68KState *env, int numr, int regr, uint32_t den)
}
}
-void HELPER(divsl)(CPUM68KState *env, int numr, int regr, int32_t den)
+void HELPER(divsl)(CPUM68KState *env, int numr, int regr,
+ int32_t den, int ilen)
{
int32_t num = env->dregs[numr];
int32_t quot, rem;
+ env->cc_c = 0; /* always cleared, even if overflow/div0 */
+
if (den == 0) {
- raise_exception_ra(env, EXCP_DIV0, GETPC());
+ raise_exception_format2(env, EXCP_DIV0, ilen, GETPC());
}
quot = num / den;
rem = num % den;
- env->cc_c = 0;
env->cc_z = quot;
env->cc_n = quot;
env->cc_v = 0;
@@ -685,19 +691,21 @@ void HELPER(divsl)(CPUM68KState *env, int numr, int regr, int32_t den)
}
}
-void HELPER(divull)(CPUM68KState *env, int numr, int regr, uint32_t den)
+void HELPER(divull)(CPUM68KState *env, int numr, int regr,
+ uint32_t den, int ilen)
{
uint64_t num = deposit64(env->dregs[numr], 32, 32, env->dregs[regr]);
uint64_t quot;
uint32_t rem;
+ env->cc_c = 0; /* always cleared, even if overflow/div0 */
+
if (den == 0) {
- raise_exception_ra(env, EXCP_DIV0, GETPC());
+ raise_exception_format2(env, EXCP_DIV0, ilen, GETPC());
}
quot = num / den;
rem = num % den;
- env->cc_c = 0; /* always cleared, even if overflow */
if (quot > 0xffffffffULL) {
env->cc_v = -1;
/*
@@ -720,19 +728,21 @@ void HELPER(divull)(CPUM68KState *env, int numr, int regr, uint32_t den)
env->dregs[numr] = quot;
}
-void HELPER(divsll)(CPUM68KState *env, int numr, int regr, int32_t den)
+void HELPER(divsll)(CPUM68KState *env, int numr, int regr,
+ int32_t den, int ilen)
{
int64_t num = deposit64(env->dregs[numr], 32, 32, env->dregs[regr]);
int64_t quot;
int32_t rem;
+ env->cc_c = 0; /* always cleared, even if overflow/div0 */
+
if (den == 0) {
- raise_exception_ra(env, EXCP_DIV0, GETPC());
+ raise_exception_format2(env, EXCP_DIV0, ilen, GETPC());
}
quot = num / den;
rem = num % den;
- env->cc_c = 0; /* always cleared, even if overflow */
if (quot != (int32_t)quot) {
env->cc_v = -1;
/*