From de262854334dabcb0e005db8f64b10ec40852c81 Mon Sep 17 00:00:00 2001 From: fridtjof Date: Mon, 4 May 2026 23:17:27 +0200 Subject: [PATCH] wip! JAL --- target/cr16c/insn.decode | 6 ++++++ target/cr16c/translate.c | 27 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/target/cr16c/insn.decode b/target/cr16c/insn.decode index 76714bdb9c..1a19aa6109 100644 --- a/target/cr16c/insn.decode +++ b/target/cr16c/insn.decode @@ -255,6 +255,12 @@ BRCOND 0001 .... cond:4 .... dest=%br_disp8 BR0 0000 11 word:1 ne:1 dest:4 src:4 +# JAL (rp,rp), pretty rare so not implemented +# JAL 0000 0000 0001 0100 1000 0000 destrp:4 linkrp:4 # fmt 1, escape2 +# JAL (ra,rp) +# this is a shorthand for the common case where the link register is RA (=14) +JAL 0000 0000 1101 destrp:4 linkrp=14 # fmt 11, param4. + JCOND 0000 1010 cond:4 ra:4 EXCP 0000 0000 1100 id:4 diff --git a/target/cr16c/translate.c b/target/cr16c/translate.c index 61704fccac..72d75768fb 100644 --- a/target/cr16c/translate.c +++ b/target/cr16c/translate.c @@ -1374,6 +1374,33 @@ static bool trans_JCOND(DisasContext* ctx, arg_JCOND *a) { return true; } +static bool trans_JAL(DisasContext* ctx, arg_JAL *a) { + // TODO JAL with a specified link regpair would be 3 words/6 bytes (fmt 3a) instead + + if (a->linkrp != 14) { + // TODO: the non-ra form has a different instruction size + // which would break the return address calculation + // technically the long encoding with RA would silently sneak by this check + // because we can't check for the decoded instruction's length here + // it's unlikely to appear in regular code though, + // because there is no reason not to use the short form + gen_helper_raise_unimplemented_instruction(tcg_env); + return true; + } + + tcg_gen_movi_i32(r[CR16C_REGNO_RA], ctx->base.pc_next); + + ctx->base.is_jmp = DISAS_NORETURN; + + tcg_gen_extract2_i32(pc, r[a->destrp], r[a->destrp+1], 0); + tcg_gen_andi_i32(pc, pc, 0xffffff); + tcg_gen_shli_i32(pc, pc, 1); + tcg_gen_lookup_and_goto_ptr(); + + // TODO CFG.SR handling + + return true; +} /* Load and Store */