This patch adds emulation for the DUP instruction flavor that copies GPR contents into vector register parts.
Signed-off-by: Alexander Graf <ag...@suse.de> --- target-arm/translate-a64.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index a864a90..ba19e10 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -833,6 +833,53 @@ static void handle_simdldstm(DisasContext *s, uint32_t insn, bool is_wback) tcg_temp_free_i64(tcg_addr); } +static void handle_dupg(DisasContext *s, uint32_t insn) +{ + int rd = get_bits(insn, 0, 5); + int rn = get_bits(insn, 5, 5); + int imm5 = get_bits(insn, 16, 6); + int q = get_bits(insn, 30, 1); + int freg_offs_d = offsetof(CPUARMState, vfp.regs[rd * 2]); + int size; + int i; + + for (size = 0; !(imm5 & (1 << size)); size++) { + if (size > 3) { + unallocated_encoding(s); + return; + } + } + + if ((size == 3) && !q) { + /* XXX reserved value */ + unallocated_encoding(s); + } + + clear_fpreg(rd); + switch (size) { + case 0: + for (i = 0; i < (q ? 16 : 8); i++) { + tcg_gen_st8_i64(cpu_reg(rn), cpu_env, freg_offs_d + i); + } + break; + case 1: + for (i = 0; i < (q ? 16 : 8); i+=2) { + tcg_gen_st16_i64(cpu_reg(rn), cpu_env, freg_offs_d + i); + } + break; + case 2: + for (i = 0; i < (q ? 16 : 8); i+=4) { + tcg_gen_st32_i64(cpu_reg(rn), cpu_env, freg_offs_d + i); + } + break; + case 3: + for (i = 0; i < (q ? 16 : 8); i+=8) { + tcg_gen_st_i64(cpu_reg(rn), cpu_env, freg_offs_d + i); + } + break; + } +} + void disas_a64_insn(CPUARMState *env, DisasContext *s) { uint32_t insn; @@ -891,6 +938,14 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s) unallocated_encoding(s); } break; + case 0x0e: + if (!get_bits(insn, 31, 1) && !get_bits(insn, 29, 1) && + (get_bits(insn, 10, 6) == 0x3)) { + handle_dupg(s, insn); + } else { + unallocated_encoding(s); + } + break; default: unallocated_encoding(s); break; -- 1.7.12.4