Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/translate.c | 70 +++++++++++++++++++++++++++++++++++++++
target/sparc/insns.decode | 8 +++++
2 files changed, 78 insertions(+)
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index d6adbf9236..877847b884 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -1243,6 +1243,66 @@ static void gen_op_fnmaddd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2, TCGv_i64 s3)
gen_helper_fmaddd(d, tcg_env, s1, s2, s3, tcg_constant_i32(op));
}
+/* Use muladd to compute (1 * src1) + src2 / 2 with one rounding. */
+static void gen_op_fhadds(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2)
+{
+ TCGv_i32 one = tcg_constant_i32(float32_one);
+ int op = float_muladd_halve_result;
+ gen_helper_fmadds(d, tcg_env, one, s1, s2, tcg_constant_i32(op));
+}
+
+static void gen_op_fhaddd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2)
+{
+ TCGv_i64 one = tcg_constant_i64(float64_one);
+ int op = float_muladd_halve_result;
+ gen_helper_fmaddd(d, tcg_env, one, s1, s2, tcg_constant_i32(op));
+}
+
+/* Use muladd to compute (1 * src1) - src2 / 2 with one rounding. */
+static void gen_op_fhsubs(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2)
+{
+ TCGv_i32 one = tcg_constant_i32(float32_one);
+ int op = float_muladd_negate_c | float_muladd_halve_result;
+ gen_helper_fmadds(d, tcg_env, one, s1, s2, tcg_constant_i32(op));
+}
+
+static void gen_op_fhsubd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2)
+{
+ TCGv_i64 one = tcg_constant_i64(float64_one);
+ int op = float_muladd_negate_c | float_muladd_halve_result;
+ gen_helper_fmaddd(d, tcg_env, one, s1, s2, tcg_constant_i32(op));
+}
+
+/* Use muladd to compute -((1 * src1) + src2 / 2) with one rounding. */
+static void gen_op_fnhadds(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2)
+{
+ TCGv_i32 one = tcg_constant_i32(float32_one);
+ int op = float_muladd_negate_result | float_muladd_halve_result;
+ gen_helper_fmadds(d, tcg_env, one, s1, s2, tcg_constant_i32(op));
+}
+
+static void gen_op_fnhaddd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2)
+{
+ TCGv_i64 one = tcg_constant_i64(float64_one);
+ int op = float_muladd_negate_result | float_muladd_halve_result;
+ gen_helper_fmaddd(d, tcg_env, one, s1, s2, tcg_constant_i32(op));
+}
+
+/* Use muladd to compute -((1 * src1) + src2). */
+static void gen_op_fnadds(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2)
+{
+ TCGv_i32 one = tcg_constant_i32(float32_one);
+ int op = float_muladd_negate_result;
+ gen_helper_fmadds(d, tcg_env, one, s1, s2, tcg_constant_i32(op));
+}
+
+static void gen_op_fnaddd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2)
+{
+ TCGv_i64 one = tcg_constant_i64(float64_one);
+ int op = float_muladd_negate_result;
+ gen_helper_fmaddd(d, tcg_env, one, s1, s2, tcg_constant_i32(op));
+}
+
static void gen_op_fpexception_im(DisasContext *dc, int ftt)
{
/*
@@ -4691,6 +4751,11 @@ TRANS(FXNORs, VIS1, do_fff, a, tcg_gen_eqv_i32)
TRANS(FORNOTs, VIS1, do_fff, a, tcg_gen_orc_i32)
TRANS(FORs, VIS1, do_fff, a, tcg_gen_or_i32)
+TRANS(FHADDs, VIS3, do_fff, a, gen_op_fhadds)
+TRANS(FHSUBs, VIS3, do_fff, a, gen_op_fhsubs)
+TRANS(FNHADDs, VIS3, do_fff, a, gen_op_fnhadds)
+TRANS(FNADDs, VIS3, do_fff, a, gen_op_fnadds)
+
static bool do_env_fff(DisasContext *dc, arg_r_r_r *a,
void (*func)(TCGv_i32, TCGv_env, TCGv_i32, TCGv_i32))
{
@@ -4804,6 +4869,11 @@ TRANS(FPACK32, VIS1, do_ddd, a, gen_op_fpack32)
TRANS(FALIGNDATAg, VIS1, do_ddd, a, gen_op_faligndata)
TRANS(BSHUFFLE, VIS2, do_ddd, a, gen_op_bshuffle)
+TRANS(FHADDd, VIS3, do_ddd, a, gen_op_fhaddd)
+TRANS(FHSUBd, VIS3, do_ddd, a, gen_op_fhsubd)
+TRANS(FNHADDd, VIS3, do_ddd, a, gen_op_fnhaddd)
+TRANS(FNADDd, VIS3, do_ddd, a, gen_op_fnaddd)
+
static bool do_rdd(DisasContext *dc, arg_r_r_r *a,
void (*func)(TCGv, TCGv_i64, TCGv_i64))
{
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 120713a28f..dc524f5b8f 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -307,8 +307,16 @@ FMULq 10 ..... 110100 ..... 0 0100 1011 ..... @q_q_q
FDIVs 10 ..... 110100 ..... 0 0100 1101 ..... @r_r_r
FDIVd 10 ..... 110100 ..... 0 0100 1110 ..... @d_d_d
FDIVq 10 ..... 110100 ..... 0 0100 1111 ..... @q_q_q
+FNADDs 10 ..... 110100 ..... 0 0101 0001 ..... @r_r_r
+FNADDd 10 ..... 110100 ..... 0 0101 0010 ..... @d_d_d
+FHADDs 10 ..... 110100 ..... 0 0110 0001 ..... @r_r_r
+FHADDd 10 ..... 110100 ..... 0 0110 0010 ..... @d_d_d
+FHSUBs 10 ..... 110100 ..... 0 0110 0101 ..... @r_r_r
+FHSUBd 10 ..... 110100 ..... 0 0110 0110 ..... @d_d_d
FsMULd 10 ..... 110100 ..... 0 0110 1001 ..... @d_r_r
FdMULq 10 ..... 110100 ..... 0 0110 1110 ..... @q_d_d
+FNHADDs 10 ..... 110100 ..... 0 0111 0001 ..... @r_r_r
+FNHADDd 10 ..... 110100 ..... 0 0111 0010 ..... @d_d_d
FsTOx 10 ..... 110100 00000 0 1000 0001 ..... @r_r2
FdTOx 10 ..... 110100 00000 0 1000 0010 ..... @r_d2
FqTOx 10 ..... 110100 00000 0 1000 0011 ..... @r_q2
--
2.34.1