Implement FMOV, ie non-converting moves between general purpose registers and floating point registers. This is a subtype of the floating point <-> integer instruction class. Signed-off-by: Peter Maydell <peter.maydell@xxxxxxxxxx> --- target-arm/translate-a64.c | 86 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 98a11cc..add8cc2 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -2751,6 +2751,63 @@ static void disas_fp_fixed_conv(DisasContext *s, uint32_t insn) unsupported_encoding(s, insn); } +static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof) +{ + /* FMOV: gpr to or from float, double, or top half of quad fp reg, + * without conversion. + */ + + if (itof) { + int freg_offs = offsetof(CPUARMState, vfp.regs[rd * 2]); + TCGv_i64 tcg_rn = cpu_reg(s, rn); + + switch (type) { + case 0: + { + /* 32 bit */ + TCGv_i64 tmp = tcg_temp_new_i64(); + tcg_gen_ext32u_i64(tmp, tcg_rn); + tcg_gen_st_i64(tmp, cpu_env, freg_offs); + tcg_gen_movi_i64(tmp, 0); + tcg_gen_st_i64(tmp, cpu_env, freg_offs + sizeof(float64)); + tcg_temp_free_i64(tmp); + break; + } + case 1: + { + /* 64 bit */ + TCGv_i64 tmp = tcg_const_i64(0); + tcg_gen_st_i64(tcg_rn, cpu_env, freg_offs); + tcg_gen_st_i64(tmp, cpu_env, freg_offs + sizeof(float64)); + tcg_temp_free_i64(tmp); + break; + } + case 2: + /* 64 bit to top half. */ + tcg_gen_st_i64(tcg_rn, cpu_env, freg_offs + sizeof(float64)); + break; + } + } else { + int freg_offs = offsetof(CPUARMState, vfp.regs[rn * 2]); + TCGv_i64 tcg_rd = cpu_reg(s, rd); + + switch (type) { + case 0: + /* 32 bit */ + tcg_gen_ld32u_i64(tcg_rd, cpu_env, freg_offs); + break; + case 2: + /* 64 bits from top half */ + freg_offs += sizeof(float64); + /* fall through */ + case 1: + /* 64 bit */ + tcg_gen_ld_i64(tcg_rd, cpu_env, freg_offs); + break; + } + } +} + /* C3.6.30 Floating point <-> integer conversions * 31 30 29 28 24 23 22 21 20 19 18 16 15 10 9 5 4 0 * +----+---+---+-----------+------+---+-------+-----+-------------+----+----+ @@ -2759,7 +2816,34 @@ static void disas_fp_fixed_conv(DisasContext *s, uint32_t insn) */ static void disas_fp_int_conv(DisasContext *s, uint32_t insn) { - unsupported_encoding(s, insn); + int rd = extract32(insn, 0, 5); + int rn = extract32(insn, 5, 5); + int opcode = extract32(insn, 16, 3); + int rmode = extract32(insn, 19, 2); + int type = extract32(insn, 22, 2); + bool sbit = extract32(insn, 29, 1); + bool sf = extract32(insn, 31, 1); + + if (!sbit && (rmode < 2) && (opcode > 5)) { + /* FMOV */ + bool itof = opcode & 1; + + switch (sf << 3 | type << 1 | rmode) { + case 0x0: /* 32 bit */ + case 0xa: /* 64 bit */ + case 0xd: /* 64 bit to top half of quad */ + break; + default: + /* all other sf/type/rmode combinations are invalid */ + unallocated_encoding(s); + break; + } + + handle_fmov(s, rd, rn, type, itof); + } else { + /* actual FP conversions */ + unsupported_encoding(s, insn); + } } /* FP-specific subcases of table C3-6 (SIMD and FP data processing) -- 1.8.5 _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm