This patch adds emulation support for variable (register based) shift instructions such as ASRV, LSLV, LSRV, RORV.
Signed-off-by: Alexander Graf <ag...@suse.de> --- target-arm/translate-a64.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 6954ff7..6e0f4bd 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -1548,6 +1548,24 @@ static void handle_div(DisasContext *s, uint32_t insn) tcg_temp_free_i64(m); } +static void handle_shift_reg(DisasContext *s, uint32_t insn) +{ + int rd = get_reg(insn); + int rn = get_bits(insn, 5, 5); + int shift_type = get_bits(insn, 10, 2); + int rm = get_bits(insn, 16, 5); + bool is_32bit = !get_bits(insn, 31, 1); + TCGv_i64 tcg_shift; + TCGv_i64 tcg_shifted; + + tcg_shift = tcg_temp_new_i64(); + tcg_gen_andi_i64(tcg_shift, cpu_reg(rm), is_32bit ? 31 : 63); + tcg_shifted = get_shift(rn, shift_type, tcg_shift, is_32bit); + tcg_gen_mov_i64(cpu_reg(rd), tcg_shifted); + tcg_temp_free_i64(tcg_shift); + tcg_temp_free_i64(tcg_shifted); +} + /* SIMD ORR */ static void handle_simdorr(DisasContext *s, uint32_t insn) { @@ -2112,6 +2130,8 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s) handle_cinc(s, insn); } else if ((insn & 0x7fe0f800) == 0x1ac00800) { handle_div(s, insn); + } else if ((insn & 0x7fe0f000) == 0x1ac02000) { + handle_shift_reg(s, insn); } else { unallocated_encoding(s); } -- 1.7.12.4