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:
Max Filippov 2011-09-06 03:55:42 +04:00 committed by Blue Swirl
parent 40643d7c0f
commit f76ebf55cd

View File

@ -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*/