static void dec_sru(DisasContext *dc) { if (dc->format == OP_FMT_RI) { LOG_DIS("srui r%d, r%d, %d\n", dc->r1, dc->r0, dc->imm5); } else { LOG_DIS("sru r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1); } if (dc->format == OP_FMT_RI) { if (!(dc->features & LM32_FEATURE_SHIFT) && (dc->imm5 != 1)) { qemu_log_mask(LOG_GUEST_ERROR, "hardware shifter is not available\n"); t_gen_illegal_insn(dc); return; } tcg_gen_shri_tl(cpu_R[dc->r1], cpu_R[dc->r0], dc->imm5); } else { TCGLabel *l1 = gen_new_label(); TCGLabel *l2 = gen_new_label(); TCGv t0 = tcg_temp_local_new(); tcg_gen_andi_tl(t0, cpu_R[dc->r1], 0x1f); if (!(dc->features & LM32_FEATURE_SHIFT)) { tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 1, l1); t_gen_illegal_insn(dc); tcg_gen_br(l2); } gen_set_label(l1); tcg_gen_shr_tl(cpu_R[dc->r2], cpu_R[dc->r0], t0); gen_set_label(l2); tcg_temp_free(t0); } }
static void gen_store_v10_conditional(DisasContext *dc, TCGv addr, TCGv val, unsigned int size, int mem_index) { int l1 = gen_new_label(); TCGv taddr = tcg_temp_local_new(); TCGv tval = tcg_temp_local_new(); TCGv t1 = tcg_temp_local_new(); dc->postinc = 0; cris_evaluate_flags(dc); tcg_gen_mov_tl(taddr, addr); tcg_gen_mov_tl(tval, val); /* Store only if F flag isn't set */ tcg_gen_andi_tl(t1, cpu_PR[PR_CCS], F_FLAG_V10); tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); if (size == 1) { tcg_gen_qemu_st8(tval, taddr, mem_index); } else if (size == 2) { tcg_gen_qemu_st16(tval, taddr, mem_index); } else { tcg_gen_qemu_st32(tval, taddr, mem_index); } gen_set_label(l1); tcg_gen_shri_tl(t1, t1, 1); /* shift F to P position */ tcg_gen_or_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], t1); /*P=F*/ tcg_temp_free(t1); tcg_temp_free(tval); tcg_temp_free(taddr); }
static void dec_b(DisasContext *dc) { if (dc->r0 == R_RA) { LOG_DIS("ret\n"); } else if (dc->r0 == R_EA) { LOG_DIS("eret\n"); } else if (dc->r0 == R_BA) { LOG_DIS("bret\n"); } else { LOG_DIS("b r%d\n", dc->r0); } /* restore IE.IE in case of an eret */ if (dc->r0 == R_EA) { TCGv t0 = tcg_temp_new(); TCGLabel *l1 = gen_new_label(); tcg_gen_andi_tl(t0, cpu_ie, IE_EIE); tcg_gen_ori_tl(cpu_ie, cpu_ie, IE_IE); tcg_gen_brcondi_tl(TCG_COND_EQ, t0, IE_EIE, l1); tcg_gen_andi_tl(cpu_ie, cpu_ie, ~IE_IE); gen_set_label(l1); tcg_temp_free(t0); } else if (dc->r0 == R_BA) { TCGv t0 = tcg_temp_new(); TCGLabel *l1 = gen_new_label(); tcg_gen_andi_tl(t0, cpu_ie, IE_BIE); tcg_gen_ori_tl(cpu_ie, cpu_ie, IE_IE); tcg_gen_brcondi_tl(TCG_COND_EQ, t0, IE_BIE, l1); tcg_gen_andi_tl(cpu_ie, cpu_ie, ~IE_IE); gen_set_label(l1); tcg_temp_free(t0); } tcg_gen_mov_tl(cpu_pc, cpu_R[dc->r0]); dc->is_jmp = DISAS_JUMP; }
static void dec_modu(DisasContext *dc) { TCGLabel *l1; LOG_DIS("modu r%d, r%d, %d\n", dc->r2, dc->r0, dc->r1); if (!(dc->features & LM32_FEATURE_DIVIDE)) { qemu_log_mask(LOG_GUEST_ERROR, "hardware divider is not available\n"); t_gen_illegal_insn(dc); return; } l1 = gen_new_label(); tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[dc->r1], 0, l1); tcg_gen_movi_tl(cpu_pc, dc->pc); t_gen_raise_exception(dc, EXCP_DIVIDE_BY_ZERO); gen_set_label(l1); tcg_gen_remu_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]); }
static void dec10_reg_scc(DisasContext *dc) { int cond = dc->dst; LOG_DIS("s%s $r%u\n", cc_name(cond), dc->src); if (cond != CC_A) { int l1; gen_tst_cc (dc, cpu_R[dc->src], cond); l1 = gen_new_label(); tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[dc->src], 0, l1); tcg_gen_movi_tl(cpu_R[dc->src], 1); gen_set_label(l1); } else { tcg_gen_movi_tl(cpu_R[dc->src], 1); } cris_cc_mask(dc, 0); }