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;
|
||||
|
||||
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;
|
||||
|
||||
case 3: /*RST3*/
|
||||
|
Loading…
Reference in New Issue
Block a user