1
From ad247280ca3dff74f4bfcfcc7ad5489ed473b790 Mon Sep 17 00:00:00 2001
2
From: Peter Maydell <peter.maydell@linaro.org>
3
Date: Tue, 7 Jan 2014 17:19:15 +0000
4
Subject: [PATCH 109/158] target-arm: A64: Add support for FCVT between half,
7
Add support for FCVT between half, single and double precision.
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <rth@twiddle.net>
12
target-arm/helper.c | 20 +++++++++++++
13
target-arm/helper.h | 2 ++
14
target-arm/translate-a64.c | 75 +++++++++++++++++++++++++++++++++++++++++++++-
15
3 files changed, 96 insertions(+), 1 deletion(-)
17
diff --git a/target-arm/helper.c b/target-arm/helper.c
18
index b84b8a1..475a7fd 100644
19
--- a/target-arm/helper.c
20
+++ b/target-arm/helper.c
21
@@ -4124,6 +4124,26 @@ uint32_t HELPER(vfp_fcvt_f32_to_f16)(float32 a, CPUARMState *env)
22
return do_fcvt_f32_to_f16(a, env, &env->vfp.fp_status);
25
+float64 HELPER(vfp_fcvt_f16_to_f64)(uint32_t a, CPUARMState *env)
27
+ int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0;
28
+ float64 r = float16_to_float64(make_float16(a), ieee, &env->vfp.fp_status);
30
+ return float64_maybe_silence_nan(r);
35
+uint32_t HELPER(vfp_fcvt_f64_to_f16)(float64 a, CPUARMState *env)
37
+ int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0;
38
+ float16 r = float64_to_float16(a, ieee, &env->vfp.fp_status);
40
+ r = float16_maybe_silence_nan(r);
42
+ return float16_val(r);
45
#define float32_two make_float32(0x40000000)
46
#define float32_three make_float32(0x40400000)
47
#define float32_one_point_five make_float32(0x3fc00000)
48
diff --git a/target-arm/helper.h b/target-arm/helper.h
49
index 329b97f..f93f643 100644
50
--- a/target-arm/helper.h
51
+++ b/target-arm/helper.h
52
@@ -154,6 +154,8 @@ DEF_HELPER_2(vfp_fcvt_f16_to_f32, f32, i32, env)
53
DEF_HELPER_2(vfp_fcvt_f32_to_f16, i32, f32, env)
54
DEF_HELPER_2(neon_fcvt_f16_to_f32, f32, i32, env)
55
DEF_HELPER_2(neon_fcvt_f32_to_f16, i32, f32, env)
56
+DEF_HELPER_FLAGS_2(vfp_fcvt_f16_to_f64, TCG_CALL_NO_RWG, f64, i32, env)
57
+DEF_HELPER_FLAGS_2(vfp_fcvt_f64_to_f16, TCG_CALL_NO_RWG, i32, f64, env)
59
DEF_HELPER_4(vfp_muladdd, f64, f64, f64, f64, ptr)
60
DEF_HELPER_4(vfp_muladds, f32, f32, f32, f32, ptr)
61
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
62
index 345a47b..cf80c46 100644
63
--- a/target-arm/translate-a64.c
64
+++ b/target-arm/translate-a64.c
65
@@ -3498,6 +3498,72 @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn)
66
tcg_temp_free_i64(tcg_res);
69
+static void handle_fp_fcvt(DisasContext *s, int opcode,
70
+ int rd, int rn, int dtype, int ntype)
75
+ TCGv_i32 tcg_rn = read_fp_sreg(s, rn);
77
+ /* Single to double */
78
+ TCGv_i64 tcg_rd = tcg_temp_new_i64();
79
+ gen_helper_vfp_fcvtds(tcg_rd, tcg_rn, cpu_env);
80
+ write_fp_dreg(s, rd, tcg_rd);
81
+ tcg_temp_free_i64(tcg_rd);
83
+ /* Single to half */
84
+ TCGv_i32 tcg_rd = tcg_temp_new_i32();
85
+ gen_helper_vfp_fcvt_f32_to_f16(tcg_rd, tcg_rn, cpu_env);
86
+ /* write_fp_sreg is OK here because top half of tcg_rd is zero */
87
+ write_fp_sreg(s, rd, tcg_rd);
88
+ tcg_temp_free_i32(tcg_rd);
90
+ tcg_temp_free_i32(tcg_rn);
95
+ TCGv_i64 tcg_rn = read_fp_dreg(s, rn);
96
+ TCGv_i32 tcg_rd = tcg_temp_new_i32();
98
+ /* Double to single */
99
+ gen_helper_vfp_fcvtsd(tcg_rd, tcg_rn, cpu_env);
101
+ /* Double to half */
102
+ gen_helper_vfp_fcvt_f64_to_f16(tcg_rd, tcg_rn, cpu_env);
103
+ /* write_fp_sreg is OK here because top half of tcg_rd is zero */
105
+ write_fp_sreg(s, rd, tcg_rd);
106
+ tcg_temp_free_i32(tcg_rd);
107
+ tcg_temp_free_i64(tcg_rn);
112
+ TCGv_i32 tcg_rn = read_fp_sreg(s, rn);
113
+ tcg_gen_ext16u_i32(tcg_rn, tcg_rn);
115
+ /* Half to single */
116
+ TCGv_i32 tcg_rd = tcg_temp_new_i32();
117
+ gen_helper_vfp_fcvt_f16_to_f32(tcg_rd, tcg_rn, cpu_env);
118
+ write_fp_sreg(s, rd, tcg_rd);
119
+ tcg_temp_free_i32(tcg_rd);
121
+ /* Half to double */
122
+ TCGv_i64 tcg_rd = tcg_temp_new_i64();
123
+ gen_helper_vfp_fcvt_f16_to_f64(tcg_rd, tcg_rn, cpu_env);
124
+ write_fp_dreg(s, rd, tcg_rd);
125
+ tcg_temp_free_i64(tcg_rd);
127
+ tcg_temp_free_i32(tcg_rn);
135
/* C3.6.25 Floating point data-processing (1 source)
136
* 31 30 29 28 24 23 22 21 20 15 14 10 9 5 4 0
137
* +---+---+---+-----------+------+---+--------+-----------+------+------+
138
@@ -3513,9 +3579,16 @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
141
case 0x4: case 0x5: case 0x7:
143
/* FCVT between half, single and double precision */
144
- unsupported_encoding(s, insn);
145
+ int dtype = extract32(opcode, 0, 2);
146
+ if (type == 2 || dtype == type) {
147
+ unallocated_encoding(s);
150
+ handle_fp_fcvt(s, opcode, rd, rn, dtype, type);