diff --git a/target/cr16c/insn.decode b/target/cr16c/insn.decode index d2681318b1..76714bdb9c 100644 --- a/target/cr16c/insn.decode +++ b/target/cr16c/insn.decode @@ -279,7 +279,7 @@ push 0000 0001 .... .... @push # fmt 14 &load rd ra dbase disp width &load_rrp rd rrp disp width -&load_abs rd addr width +&load_abs rd addr width remap &load_ind_abs rd ri addr width %load_disp20 40:4 16:s16 @@ -291,10 +291,10 @@ push 0000 0001 .... .... @push # fmt 14 @load_disp20_reg .... .... .... .... .... .... rd:4 ra:4 .... .... .... .... disp=%load_disp20 &load @load_disp20_rrp .... .... .... .... .... .... rd:4 rrp:4 .... .... .... .... disp=%load_disp20 &load_rrp @load_disp20_rp .... .... .... .... .... .... rd:4 ra:4 .... .... .... .... disp=%load_disp20 &load -@load_abs20 .... .... rd:4 .... .... .... .... .... addr=%addr_abs20 &load_abs +@load_abs20 .... .... rd:4 .... .... .... .... .... addr=%addr_abs20 remap=1 &load_abs @load_ind_abs .... ... ri:1 rd:4 addr:20 &load_ind_abs @load_disp4_reg .... .... rd:4 ra:4 &load -@load_abs24 .... .... .... .... .... .... rd:4 .... .... .... .... .... addr=%addr_disp24 &load_abs +@load_abs24 .... .... .... .... .... .... rd:4 .... .... .... .... .... addr=%addr_disp24 remap=0 &load_abs #@load_disp14_rrp .... .... .... rrp:4 .... .... rd:4 .... disp=%load_disp14 &load_rrp { diff --git a/target/cr16c/translate.c b/target/cr16c/translate.c index d121bbec3a..3a24754e86 100644 --- a/target/cr16c/translate.c +++ b/target/cr16c/translate.c @@ -1393,10 +1393,23 @@ static bool trans_LOAD(DisasContext *ctx, arg_LOAD *a) { return true; } +// TODO this should already be in reloc_abs20. see how to replace this in the decoder +static int abs20_remap(int addr) { + if (addr > 0xEFFFF) + return addr | 0xF00000; + return addr; +} + static bool trans_LOAD_abs(DisasContext *ctx, arg_LOAD_abs *a) { TCGv_i32 temp = tcg_temp_new_i32(); - tcg_gen_qemu_ld_i32(temp, tcg_constant_i32(a->addr), 0, unsigned_op_by_width[a->width]); + // See Table 5-7, footnote f, which applies for abs20 + int addr = a->addr; + if (a->remap) { + addr = abs20_remap(addr); + } + + tcg_gen_qemu_ld_i32(temp, tcg_constant_i32(addr), 0, unsigned_op_by_width[a->width]); gen_move_dest(temp, a->rd, a->width); return true; @@ -1464,13 +1477,6 @@ static bool trans_STOR_rrp(DisasContext *ctx, arg_STOR_rrp *a) { return true; } -// TODO this should already be in reloc_abs20. see how to replace this in the decoder -static int abs20_remap(int addr) { - if (addr > 0xEFFFF) - return addr | 0xF00000; - return addr; -} - static bool trans_STOR_abs(DisasContext *ctx, arg_STOR_abs *a) { int32_t addr = a->addr;