diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode index 5811a679db..a5f5d2681e 100644 --- a/target/sparc/insns.decode +++ b/target/sparc/insns.decode @@ -3,3 +3,4 @@ # Sparc instruction decode definitions. # Copyright (c) 2023 Richard Henderson +CALL 01 i:s30 diff --git a/target/sparc/translate.c b/target/sparc/translate.c index 9eb2b7e52f..7ef4c6d4f7 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -285,6 +285,11 @@ static void gen_address_mask(DisasContext *dc, TCGv addr) } } +static target_ulong address_mask_i(DisasContext *dc, target_ulong addr) +{ + return AM_CHECK(dc) ? (uint32_t)addr : addr; +} + static TCGv gen_load_gpr(DisasContext *dc, int reg) { if (reg > 0) { @@ -3041,6 +3046,16 @@ static bool advance_pc(DisasContext *dc) return true; } +static bool trans_CALL(DisasContext *dc, arg_CALL *a) +{ + target_long target = address_mask_i(dc, dc->pc + a->i * 4); + + gen_store_gpr(dc, 15, tcg_constant_tl(dc->pc)); + gen_mov_pc_npc(dc); + dc->npc = target; + return true; +} + #define CHECK_IU_FEATURE(dc, FEATURE) \ if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \ goto illegal_insn; @@ -3146,23 +3161,8 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn) break; } break; - case 1: /*CALL*/ - { - target_long target = GET_FIELDs(insn, 2, 31) << 2; - TCGv o7 = gen_dest_gpr(dc, 15); - - tcg_gen_movi_tl(o7, dc->pc); - gen_store_gpr(dc, 15, o7); - target += dc->pc; - gen_mov_pc_npc(dc); -#ifdef TARGET_SPARC64 - if (unlikely(AM_CHECK(dc))) { - target &= 0xffffffffULL; - } -#endif - dc->npc = target; - } - goto jmp_insn; + case 1: + g_assert_not_reached(); /* in decodetree */ case 2: /* FPU & Logical Operations */ { unsigned int xop = GET_FIELD(insn, 7, 12);