aboutsummaryrefslogtreecommitdiff
path: root/target/m68k/translate.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/m68k/translate.c')
-rw-r--r--target/m68k/translate.c84
1 files changed, 47 insertions, 37 deletions
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 6678b57b97..737009e0b5 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -1242,64 +1242,74 @@ DISAS_INSN(mulw)
DISAS_INSN(divw)
{
- TCGv reg;
- TCGv tmp;
- TCGv src;
int sign;
+ TCGv src;
+ TCGv destr;
+
+ /* divX.w <EA>,Dn 32/16 -> 16r:16q */
sign = (insn & 0x100) != 0;
- reg = DREG(insn, 9);
- if (sign) {
- tcg_gen_ext16s_i32(QREG_DIV1, reg);
- } else {
- tcg_gen_ext16u_i32(QREG_DIV1, reg);
- }
+
+ /* dest.l / src.w */
+
SRC_EA(env, src, OS_WORD, sign, NULL);
- tcg_gen_mov_i32(QREG_DIV2, src);
+ destr = tcg_const_i32(REG(insn, 9));
if (sign) {
- gen_helper_divs(cpu_env, tcg_const_i32(1));
+ gen_helper_divsw(cpu_env, destr, src);
} else {
- gen_helper_divu(cpu_env, tcg_const_i32(1));
+ gen_helper_divuw(cpu_env, destr, src);
}
-
- tmp = tcg_temp_new();
- src = tcg_temp_new();
- tcg_gen_ext16u_i32(tmp, QREG_DIV1);
- tcg_gen_shli_i32(src, QREG_DIV2, 16);
- tcg_gen_or_i32(reg, tmp, src);
+ tcg_temp_free(destr);
set_cc_op(s, CC_OP_FLAGS);
}
DISAS_INSN(divl)
{
- TCGv num;
- TCGv den;
- TCGv reg;
+ TCGv num, reg, den;
+ int sign;
uint16_t ext;
ext = read_im16(env, s);
- if (ext & 0x87f8) {
- gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
+
+ sign = (ext & 0x0800) != 0;
+
+ if (ext & 0x400) {
+ if (!m68k_feature(s->env, M68K_FEATURE_QUAD_MULDIV)) {
+ gen_exception(s, s->insn_pc, EXCP_ILLEGAL);
+ return;
+ }
+
+ /* divX.l <EA>, Dr:Dq 64/32 -> 32r:32q */
+
+ SRC_EA(env, den, OS_LONG, 0, NULL);
+ num = tcg_const_i32(REG(ext, 12));
+ reg = tcg_const_i32(REG(ext, 0));
+ if (sign) {
+ gen_helper_divsll(cpu_env, num, reg, den);
+ } else {
+ gen_helper_divull(cpu_env, num, reg, den);
+ }
+ tcg_temp_free(reg);
+ tcg_temp_free(num);
+ set_cc_op(s, CC_OP_FLAGS);
return;
}
- num = DREG(ext, 12);
- reg = DREG(ext, 0);
- tcg_gen_mov_i32(QREG_DIV1, num);
+
+ /* divX.l <EA>, Dq 32/32 -> 32q */
+ /* divXl.l <EA>, Dr:Dq 32/32 -> 32r:32q */
+
SRC_EA(env, den, OS_LONG, 0, NULL);
- tcg_gen_mov_i32(QREG_DIV2, den);
- if (ext & 0x0800) {
- gen_helper_divs(cpu_env, tcg_const_i32(0));
- } else {
- gen_helper_divu(cpu_env, tcg_const_i32(0));
- }
- if ((ext & 7) == ((ext >> 12) & 7)) {
- /* div */
- tcg_gen_mov_i32 (reg, QREG_DIV1);
+ num = tcg_const_i32(REG(ext, 12));
+ reg = tcg_const_i32(REG(ext, 0));
+ if (sign) {
+ gen_helper_divsl(cpu_env, num, reg, den);
} else {
- /* rem */
- tcg_gen_mov_i32 (reg, QREG_DIV2);
+ gen_helper_divul(cpu_env, num, reg, den);
}
+ tcg_temp_free(reg);
+ tcg_temp_free(num);
+
set_cc_op(s, CC_OP_FLAGS);
}