From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42876) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W08On-0000Fp-3U for qemu-devel@nongnu.org; Mon, 06 Jan 2014 06:31:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1W08Ol-0004PE-UC for qemu-devel@nongnu.org; Mon, 06 Jan 2014 06:31:13 -0500 Received: from mnementh.archaic.org.uk ([2001:8b0:1d0::1]:44217) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W08Ol-0004P7-K8 for qemu-devel@nongnu.org; Mon, 06 Jan 2014 06:31:11 -0500 From: Peter Maydell Date: Mon, 6 Jan 2014 11:30:15 +0000 Message-Id: <1389007857-14649-11-git-send-email-peter.maydell@linaro.org> In-Reply-To: <1389007857-14649-1-git-send-email-peter.maydell@linaro.org> References: <1389007857-14649-1-git-send-email-peter.maydell@linaro.org> Subject: [Qemu-devel] [PULL 10/52] target-arm: A64: implement FMOV List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Anthony Liguori Cc: Blue Swirl , qemu-devel@nongnu.org, Aurelien Jarno 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 Reviewed-by: Richard Henderson --- 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 079c2f7..7d98337 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -2758,6 +2758,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 * +----+---+---+-----------+------+---+-------+-----+-------------+----+----+ @@ -2766,7 +2823,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