diff --git a/target/cr16c/insn.decode b/target/cr16c/insn.decode index 74ec7a42a5..9882b3fad9 100644 --- a/target/cr16c/insn.decode +++ b/target/cr16c/insn.decode @@ -158,9 +158,9 @@ LSHD_rp 0100 0111 .... .... @shiftd_rp ### Jumps and Linkeage ### -%br_disp8 56:4 48:4 !function=get_disp8 +%br_disp8 56:s4 48:4 !function=disp8_get_dest -BRCOND 0001 .... cond:4 .... disp=%br_disp8 +BRCOND 0001 .... cond:4 .... dest=%br_disp8 JCOND 0000 1010 cond:4 ra:4 diff --git a/target/cr16c/translate.c b/target/cr16c/translate.c index 677b5a4d43..d939bf5ad8 100644 --- a/target/cr16c/translate.c +++ b/target/cr16c/translate.c @@ -106,15 +106,16 @@ static uint8_t get_disp4(DisasContext *ctx, uint8_t disp) { return disp << 1; } -static uint16_t get_disp8(DisasContext* ctx, uint8_t disp) { - if (disp == 0x80) { - uint16_t disp_esc = cpu_lduw_code(ctx->env, ctx->base.pc_next) >> 1; +static int32_t disp8_get_dest(DisasContext* ctx, int32_t disp) { + int32_t dest = ctx->base.pc_next - 2; + if (disp == 0xFFFFFF80) { + dest += cpu_ldsw_le_data(ctx->env, ctx->base.pc_next); ctx->base.pc_next += 2; - return disp_esc; } else { - return disp; + dest += disp << 1; } + return dest; }; static uint32_t reloc_abs20(DisasContext *ctx, uint32_t addr) { @@ -280,7 +281,7 @@ static void gen_ADDD_imm(int regnl, int32_t imm) { } tcg_gen_extu_i32_i64(temp_res, temp_h); - tcg_gen_addi_i64(temp_res, temp_res, imm); + tcg_gen_addi_i64(temp_res, temp_res, imm & 0xFFFFFFFF); tcg_gen_extrl_i64_i32(regl, temp_res); /* Carry flag */ @@ -1127,17 +1128,13 @@ static void gen_br_cond(DisasContext* ctx, int cond, TCGLabel* l) { static bool trans_BRCOND(DisasContext* ctx, arg_BRCOND *a) { TCGLabel* l = gen_new_label(); - gen_br_cond(ctx, a->cond, l); - uint32_t pc_this = ctx->base.pc_next - 2; - uint32_t dest = pc_this + a->disp*2; - gen_goto(&ctx->base, ctx->base.pc_next, 0); gen_set_label(l); - gen_goto(&ctx->base, dest, 1); + gen_goto(&ctx->base, a->dest, 1); ctx->base.is_jmp = DISAS_NORETURN; return true;