mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 17:35:33 +00:00
target-m68k: add 680x0 divu/divs variants
Update helper to set the throwing location in case of div-by-0. Cleanup divX.w and add quad word variants of divX.l. Backports commit 0ccb9c1d8128a020720d5c6abf99a470742a1b94 from qemu
This commit is contained in:
parent
77b8b2f3b8
commit
90b87b3580
|
@ -1259,31 +1259,24 @@ DISAS_INSN(mulw)
|
||||||
DISAS_INSN(divw)
|
DISAS_INSN(divw)
|
||||||
{
|
{
|
||||||
TCGContext *tcg_ctx = s->uc->tcg_ctx;
|
TCGContext *tcg_ctx = s->uc->tcg_ctx;
|
||||||
TCGv reg;
|
|
||||||
TCGv tmp;
|
|
||||||
TCGv src;
|
|
||||||
int sign;
|
int sign;
|
||||||
|
TCGv src;
|
||||||
|
TCGv destr;
|
||||||
|
|
||||||
|
/* divX.w <EA>,Dn 32/16 -> 16r:16q */
|
||||||
|
|
||||||
sign = (insn & 0x100) != 0;
|
sign = (insn & 0x100) != 0;
|
||||||
reg = DREG(insn, 9);
|
|
||||||
if (sign) {
|
|
||||||
tcg_gen_ext16s_i32(tcg_ctx, tcg_ctx->QREG_DIV1, reg);
|
|
||||||
} else {
|
|
||||||
tcg_gen_ext16u_i32(tcg_ctx, tcg_ctx->QREG_DIV1, reg);
|
|
||||||
}
|
|
||||||
SRC_EA(env, src, OS_WORD, sign, NULL);
|
|
||||||
tcg_gen_mov_i32(tcg_ctx, tcg_ctx->QREG_DIV2, src);
|
|
||||||
if (sign) {
|
|
||||||
gen_helper_divs(tcg_ctx, tcg_ctx->cpu_env, tcg_const_i32(tcg_ctx, 1));
|
|
||||||
} else {
|
|
||||||
gen_helper_divu(tcg_ctx, tcg_ctx->cpu_env, tcg_const_i32(tcg_ctx, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = tcg_temp_new(tcg_ctx);
|
/* dest.l / src.w */
|
||||||
src = tcg_temp_new(tcg_ctx);
|
|
||||||
tcg_gen_ext16u_i32(tcg_ctx, tmp, tcg_ctx->QREG_DIV1);
|
SRC_EA(env, src, OS_WORD, sign, NULL);
|
||||||
tcg_gen_shli_i32(tcg_ctx, src, tcg_ctx->QREG_DIV2, 16);
|
destr = tcg_const_i32(tcg_ctx, REG(insn, 9));
|
||||||
tcg_gen_or_i32(tcg_ctx, reg, tmp, src);
|
if (sign) {
|
||||||
|
gen_helper_divsw(tcg_ctx, tcg_ctx->cpu_env, destr, src);
|
||||||
|
} else {
|
||||||
|
gen_helper_divuw(tcg_ctx, tcg_ctx->cpu_env, destr, src);
|
||||||
|
}
|
||||||
|
tcg_temp_free(tcg_ctx, destr);
|
||||||
|
|
||||||
set_cc_op(s, CC_OP_FLAGS);
|
set_cc_op(s, CC_OP_FLAGS);
|
||||||
}
|
}
|
||||||
|
@ -1291,33 +1284,49 @@ DISAS_INSN(divw)
|
||||||
DISAS_INSN(divl)
|
DISAS_INSN(divl)
|
||||||
{
|
{
|
||||||
TCGContext *tcg_ctx = s->uc->tcg_ctx;
|
TCGContext *tcg_ctx = s->uc->tcg_ctx;
|
||||||
TCGv num;
|
TCGv num, reg, den;
|
||||||
TCGv den;
|
int sign;
|
||||||
TCGv reg;
|
|
||||||
uint16_t ext;
|
uint16_t ext;
|
||||||
|
|
||||||
ext = read_im16(env, s);
|
ext = read_im16(env, s);
|
||||||
if (ext & 0x87f8) {
|
sign = (ext & 0x0800) != 0;
|
||||||
gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
|
|
||||||
|
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(tcg_ctx, REG(ext, 12));
|
||||||
|
reg = tcg_const_i32(tcg_ctx, REG(ext, 0));
|
||||||
|
if (sign) {
|
||||||
|
gen_helper_divsll(tcg_ctx, tcg_ctx->cpu_env, num, reg, den);
|
||||||
|
} else {
|
||||||
|
gen_helper_divull(tcg_ctx, tcg_ctx->cpu_env, num, reg, den);
|
||||||
|
}
|
||||||
|
tcg_temp_free(tcg_ctx, reg);
|
||||||
|
tcg_temp_free(tcg_ctx, num);
|
||||||
|
set_cc_op(s, CC_OP_FLAGS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
num = DREG(ext, 12);
|
|
||||||
reg = DREG(ext, 0);
|
/* divX.l <EA>, Dq 32/32 -> 32q */
|
||||||
tcg_gen_mov_i32(tcg_ctx, tcg_ctx->QREG_DIV1, num);
|
/* divXl.l <EA>, Dr:Dq 32/32 -> 32r:32q */
|
||||||
|
|
||||||
SRC_EA(env, den, OS_LONG, 0, NULL);
|
SRC_EA(env, den, OS_LONG, 0, NULL);
|
||||||
tcg_gen_mov_i32(tcg_ctx, tcg_ctx->QREG_DIV2, den);
|
num = tcg_const_i32(tcg_ctx, REG(ext, 12));
|
||||||
if (ext & 0x0800) {
|
reg = tcg_const_i32(tcg_ctx, REG(ext, 0));
|
||||||
gen_helper_divs(tcg_ctx, tcg_ctx->cpu_env, tcg_const_i32(tcg_ctx, 0));
|
if (sign) {
|
||||||
|
gen_helper_divsl(tcg_ctx, tcg_ctx->cpu_env, num, reg, den);
|
||||||
} else {
|
} else {
|
||||||
gen_helper_divu(tcg_ctx, tcg_ctx->cpu_env, tcg_const_i32(tcg_ctx, 0));
|
gen_helper_divul(tcg_ctx, tcg_ctx->cpu_env, num, reg, den);
|
||||||
}
|
|
||||||
if ((ext & 7) == ((ext >> 12) & 7)) {
|
|
||||||
/* div */
|
|
||||||
tcg_gen_mov_i32 (tcg_ctx, reg, tcg_ctx->QREG_DIV1);
|
|
||||||
} else {
|
|
||||||
/* rem */
|
|
||||||
tcg_gen_mov_i32 (tcg_ctx, reg, tcg_ctx->QREG_DIV2);
|
|
||||||
}
|
}
|
||||||
|
tcg_temp_free(tcg_ctx, reg);
|
||||||
|
tcg_temp_free(tcg_ctx, num);
|
||||||
|
|
||||||
set_cc_op(s, CC_OP_FLAGS);
|
set_cc_op(s, CC_OP_FLAGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue