mirror of https://github.com/xqemu/xqemu.git
target-xtensa: implement RST2 group (32 bit mul/div/rem)
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
This commit is contained in:
parent
40643d7c0f
commit
f76ebf55cd
|
@ -878,7 +878,82 @@ static void disas_xtensa_insn(DisasContext *dc)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: /*RST2*/
|
case 2: /*RST2*/
|
||||||
TBD();
|
if (OP2 >= 12) {
|
||||||
|
HAS_OPTION(XTENSA_OPTION_32_BIT_IDIV);
|
||||||
|
int label = gen_new_label();
|
||||||
|
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_T], 0, label);
|
||||||
|
gen_exception_cause(dc, INTEGER_DIVIDE_BY_ZERO_CAUSE);
|
||||||
|
gen_set_label(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (OP2) {
|
||||||
|
case 8: /*MULLi*/
|
||||||
|
HAS_OPTION(XTENSA_OPTION_32_BIT_IMUL);
|
||||||
|
tcg_gen_mul_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 10: /*MULUHi*/
|
||||||
|
case 11: /*MULSHi*/
|
||||||
|
HAS_OPTION(XTENSA_OPTION_32_BIT_IMUL);
|
||||||
|
{
|
||||||
|
TCGv_i64 r = tcg_temp_new_i64();
|
||||||
|
TCGv_i64 s = tcg_temp_new_i64();
|
||||||
|
TCGv_i64 t = tcg_temp_new_i64();
|
||||||
|
|
||||||
|
if (OP2 == 10) {
|
||||||
|
tcg_gen_extu_i32_i64(s, cpu_R[RRR_S]);
|
||||||
|
tcg_gen_extu_i32_i64(t, cpu_R[RRR_T]);
|
||||||
|
} else {
|
||||||
|
tcg_gen_ext_i32_i64(s, cpu_R[RRR_S]);
|
||||||
|
tcg_gen_ext_i32_i64(t, cpu_R[RRR_T]);
|
||||||
|
}
|
||||||
|
tcg_gen_mul_i64(r, s, t);
|
||||||
|
tcg_gen_shri_i64(r, r, 32);
|
||||||
|
tcg_gen_trunc_i64_i32(cpu_R[RRR_R], r);
|
||||||
|
|
||||||
|
tcg_temp_free_i64(r);
|
||||||
|
tcg_temp_free_i64(s);
|
||||||
|
tcg_temp_free_i64(t);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 12: /*QUOUi*/
|
||||||
|
tcg_gen_divu_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 13: /*QUOSi*/
|
||||||
|
case 15: /*REMSi*/
|
||||||
|
{
|
||||||
|
int label1 = gen_new_label();
|
||||||
|
int label2 = gen_new_label();
|
||||||
|
|
||||||
|
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_S], 0x80000000,
|
||||||
|
label1);
|
||||||
|
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_T], 0xffffffff,
|
||||||
|
label1);
|
||||||
|
tcg_gen_movi_i32(cpu_R[RRR_R],
|
||||||
|
OP2 == 13 ? 0x80000000 : 0);
|
||||||
|
tcg_gen_br(label2);
|
||||||
|
gen_set_label(label1);
|
||||||
|
if (OP2 == 13) {
|
||||||
|
tcg_gen_div_i32(cpu_R[RRR_R],
|
||||||
|
cpu_R[RRR_S], cpu_R[RRR_T]);
|
||||||
|
} else {
|
||||||
|
tcg_gen_rem_i32(cpu_R[RRR_R],
|
||||||
|
cpu_R[RRR_S], cpu_R[RRR_T]);
|
||||||
|
}
|
||||||
|
gen_set_label(label2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 14: /*REMUi*/
|
||||||
|
tcg_gen_remu_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: /*reserved*/
|
||||||
|
RESERVED();
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: /*RST3*/
|
case 3: /*RST3*/
|
||||||
|
|
Loading…
Reference in New Issue