Implement the v83 two-lane scalar floating-point arithmetic instructions.
Signed-off-by: Brian Cain <[email protected]>
---
target/hexagon/gen_tcg.h | 10 ++++
target/hexagon/helper.h | 5 ++
target/hexagon/op_helper.c | 73 +++++++++++++++++++++++++++
target/hexagon/tag_rev_info.c.inc | 5 ++
target/hexagon/imported/encode_pp.def | 5 ++
target/hexagon/imported/float.idef | 49 ++++++++++++++++++
6 files changed, 147 insertions(+)
diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index d4f6d34a29d..0213ad3ecee 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -1336,6 +1336,16 @@
gen_helper_sfadd(RdV, tcg_env, RsV, RtV, pkt_need_commit)
#define fGEN_TCG_F2_sfsub(SHORTCODE) \
gen_helper_sfsub(RdV, tcg_env, RsV, RtV, pkt_need_commit)
+#define fGEN_TCG_F7_vsfadd(SHORTCODE) \
+ gen_helper_vsfadd(RddV, tcg_env, RssV, RttV, pkt_need_commit)
+#define fGEN_TCG_F7_vsfsub(SHORTCODE) \
+ gen_helper_vsfsub(RddV, tcg_env, RssV, RttV, pkt_need_commit)
+#define fGEN_TCG_F7_vsfmpy(SHORTCODE) \
+ gen_helper_vsfmpy(RddV, tcg_env, RssV, RttV, pkt_need_commit)
+#define fGEN_TCG_F7_vsffma(SHORTCODE) \
+ gen_helper_vsffma(RxxV, tcg_env, RxxV, RssV, RttV, pkt_need_commit)
+#define fGEN_TCG_F7_vsffms(SHORTCODE) \
+ gen_helper_vsffms(RxxV, tcg_env, RxxV, RssV, RttV, pkt_need_commit)
#define fGEN_TCG_F2_sfcmpeq(SHORTCODE) \
gen_helper_sfcmpeq(PdV, tcg_env, RsV, RtV, pkt_need_commit)
#define fGEN_TCG_F2_sfcmpgt(SHORTCODE) \
diff --git a/target/hexagon/helper.h b/target/hexagon/helper.h
index 997d87e38e6..4330d92171a 100644
--- a/target/hexagon/helper.h
+++ b/target/hexagon/helper.h
@@ -60,6 +60,11 @@ DEF_HELPER_3(conv_df2ud_chop, i64, env, f64, i32)
DEF_HELPER_3(conv_df2d_chop, s64, env, f64, i32)
DEF_HELPER_4(sfadd, f32, env, f32, f32, i32)
DEF_HELPER_4(sfsub, f32, env, f32, f32, i32)
+DEF_HELPER_4(vsfadd, i64, env, i64, i64, i32)
+DEF_HELPER_4(vsfsub, i64, env, i64, i64, i32)
+DEF_HELPER_4(vsfmpy, i64, env, i64, i64, i32)
+DEF_HELPER_5(vsffma, i64, env, i64, i64, i64, i32)
+DEF_HELPER_5(vsffms, i64, env, i64, i64, i64, i32)
DEF_HELPER_4(sfcmpeq, s32, env, f32, f32, i32)
DEF_HELPER_4(sfcmpgt, s32, env, f32, f32, i32)
DEF_HELPER_4(sfcmpge, s32, env, f32, f32, i32)
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index accadd7927a..9ae9d83fe33 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -926,6 +926,79 @@ float32 HELPER(sfsub)(CPUHexagonState *env, float32 RsV,
float32 RtV,
return RdV;
}
+uint64_t HELPER(vsfadd)(CPUHexagonState *env, uint64_t RssV, uint64_t RttV,
+ uint32_t pkt_need_commit)
+{
+ uint64_t RddV;
+ float32 lo, hi;
+
+ arch_fpop_start(env);
+ lo = float32_add(RssV, RttV, &env->fp_status);
+ hi = float32_add(RssV >> 32, RttV >> 32, &env->fp_status);
+ arch_fpop_end(env, pkt_need_commit);
+ RddV = lo | ((uint64_t)hi << 32);
+ return RddV;
+}
+
+uint64_t HELPER(vsfsub)(CPUHexagonState *env, uint64_t RssV, uint64_t RttV,
+ uint32_t pkt_need_commit)
+{
+ uint64_t RddV;
+ float32 lo, hi;
+
+ arch_fpop_start(env);
+ lo = float32_sub(RssV, RttV, &env->fp_status);
+ hi = float32_sub(RssV >> 32, RttV >> 32, &env->fp_status);
+ arch_fpop_end(env, pkt_need_commit);
+ RddV = lo | ((uint64_t)hi << 32);
+ return RddV;
+}
+
+uint64_t HELPER(vsfmpy)(CPUHexagonState *env, uint64_t RssV, uint64_t RttV,
+ uint32_t pkt_need_commit)
+{
+ uint64_t RddV;
+ float32 lo, hi;
+
+ arch_fpop_start(env);
+ lo = float32_mul(RssV, RttV, &env->fp_status);
+ hi = float32_mul(RssV >> 32, RttV >> 32, &env->fp_status);
+ arch_fpop_end(env, pkt_need_commit);
+ RddV = lo | ((uint64_t)hi << 32);
+ return RddV;
+}
+
+uint64_t HELPER(vsffma)(CPUHexagonState *env, uint64_t RxxV, uint64_t RssV,
+ uint64_t RttV, uint32_t pkt_need_commit)
+{
+ uint64_t RddV;
+ float32 lo, hi;
+
+ arch_fpop_start(env);
+ lo = float32_muladd(RssV, RttV, RxxV, 0, &env->fp_status);
+ hi = float32_muladd(RssV >> 32, RttV >> 32, RxxV >> 32, 0,
+ &env->fp_status);
+ arch_fpop_end(env, pkt_need_commit);
+ RddV = lo | ((uint64_t)hi << 32);
+ return RddV;
+}
+
+uint64_t HELPER(vsffms)(CPUHexagonState *env, uint64_t RxxV, uint64_t RssV,
+ uint64_t RttV, uint32_t pkt_need_commit)
+{
+ uint64_t RddV;
+ float32 lo, hi;
+
+ arch_fpop_start(env);
+ lo = float32_muladd(RssV, RttV, RxxV, float_muladd_negate_product,
+ &env->fp_status);
+ hi = float32_muladd(RssV >> 32, RttV >> 32, RxxV >> 32,
+ float_muladd_negate_product, &env->fp_status);
+ arch_fpop_end(env, pkt_need_commit);
+ RddV = lo | ((uint64_t)hi << 32);
+ return RddV;
+}
+
int32_t HELPER(sfcmpeq)(CPUHexagonState *env, float32 RsV, float32 RtV,
uint32_t pkt_need_commit)
{
diff --git a/target/hexagon/tag_rev_info.c.inc
b/target/hexagon/tag_rev_info.c.inc
index 88958b334d8..da0b1a648cf 100644
--- a/target/hexagon/tag_rev_info.c.inc
+++ b/target/hexagon/tag_rev_info.c.inc
@@ -728,6 +728,11 @@ static const struct tag_rev_info
tag_rev_info[XX_LAST_OPCODE] = {
.removed = HEX_VER_NONE },
[A2_nop_rb] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
[J2_trap2] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
+ [F7_vsfadd] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
+ [F7_vsfsub] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
+ [F7_vsfmpy] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
+ [F7_vsffma] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
+ [F7_vsffms] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
[Y4_dcfetch_multi] = { .introduced = HEX_VER_V85,
.removed = HEX_VER_NONE },
diff --git a/target/hexagon/imported/encode_pp.def
b/target/hexagon/imported/encode_pp.def
index 97af0fcb394..1e632050eac 100644
--- a/target/hexagon/imported/encode_pp.def
+++ b/target/hexagon/imported/encode_pp.def
@@ -1200,9 +1200,14 @@ MPY_ENC(A6_vminub_RdP,
"1010","ddddd","0","1","1","1","ee")
DEF_FIELDROW_DESC32(ICLASS_M" 1011 -------- PP------ --------","[#11]
Reserved")
MPY_ENC(F2_sfadd, "1011","ddddd","0","0","0","0","00")
MPY_ENC(F2_sfsub, "1011","ddddd","0","0","0","0","01")
+DEF_ENC32(F7_vsfadd, "11101011000sssssPP0ttttt010ddddd")
+DEF_ENC32(F7_vsfsub, "11101011000sssssPP0ttttt011ddddd")
MPY_ENC(F2_sfmax, "1011","ddddd","0","0","0","1","00")
MPY_ENC(F2_sfmin, "1011","ddddd","0","0","0","1","01")
MPY_ENC(F2_sfmpy, "1011","ddddd","0","0","1","0","00")
+DEF_ENC32(F7_vsfmpy, "11101011010sssssPP0ttttt001ddddd")
+DEF_ENC32(F7_vsffma, "11101011010sssssPP0ttttt010xxxxx")
+DEF_ENC32(F7_vsffms, "11101011010sssssPP0ttttt011xxxxx")
MPY_ENC(F2_sffixupn, "1011","ddddd","0","0","1","1","00")
MPY_ENC(F2_sffixupd, "1011","ddddd","0","0","1","1","01")
MPY_ENC(F2_sfrecipa, "1011","ddddd","1","1","1","1","ee")
diff --git a/target/hexagon/imported/float.idef
b/target/hexagon/imported/float.idef
index 3e75bc46047..e61b7f580d2 100644
--- a/target/hexagon/imported/float.idef
+++ b/target/hexagon/imported/float.idef
@@ -51,6 +51,55 @@ Q6INSN(F2_sffms,"Rx32-=sfmpy(Rs32,Rt32)",ATTRIBS(),
"Floating-Point Fused Multiply Add",
{ RxV=fUNFLOAT(fFMAF(-fFLOAT(RsV),fFLOAT(RtV),fFLOAT(RxV))); })
+Q6INSN(F7_vsfadd,"Rdd32=vsfadd(Rss32,Rtt32)",ATTRIBS(),
+ "Vector Floating-Point Add",
+{
+ fSETWORD(0,RddV,fUNFLOAT(fFLOAT(fGETUWORD(0,RssV)) +
+ fFLOAT(fGETUWORD(0,RttV))));
+ fSETWORD(1,RddV,fUNFLOAT(fFLOAT(fGETUWORD(1,RssV)) +
+ fFLOAT(fGETUWORD(1,RttV))));
+})
+
+Q6INSN(F7_vsfsub,"Rdd32=vsfsub(Rss32,Rtt32)",ATTRIBS(),
+ "Vector Floating-Point Subtract",
+{
+ fSETWORD(0,RddV,fUNFLOAT(fFLOAT(fGETUWORD(0,RssV)) -
+ fFLOAT(fGETUWORD(0,RttV))));
+ fSETWORD(1,RddV,fUNFLOAT(fFLOAT(fGETUWORD(1,RssV)) -
+ fFLOAT(fGETUWORD(1,RttV))));
+})
+
+Q6INSN(F7_vsfmpy,"Rdd32=vsfmpy(Rss32,Rtt32)",ATTRIBS(),
+ "Vector Floating-Point Multiply",
+{
+ fSETWORD(0,RddV,fUNFLOAT(fSFMPY(fFLOAT(fGETUWORD(0,RssV)),
+ fFLOAT(fGETUWORD(0,RttV)))));
+ fSETWORD(1,RddV,fUNFLOAT(fSFMPY(fFLOAT(fGETUWORD(1,RssV)),
+ fFLOAT(fGETUWORD(1,RttV)))));
+})
+
+Q6INSN(F7_vsffma,"Rxx32+=vsfmpy(Rss32,Rtt32)",ATTRIBS(),
+ "Vector Floating-Point Fused Multiply Add",
+{
+ fSETWORD(0,RxxV,fUNFLOAT(fFMAF(fFLOAT(fGETUWORD(0,RssV)),
+ fFLOAT(fGETUWORD(0,RttV)),
+ fFLOAT(fGETUWORD(0,RxxV)))));
+ fSETWORD(1,RxxV,fUNFLOAT(fFMAF(fFLOAT(fGETUWORD(1,RssV)),
+ fFLOAT(fGETUWORD(1,RttV)),
+ fFLOAT(fGETUWORD(1,RxxV)))));
+})
+
+Q6INSN(F7_vsffms,"Rxx32-=vsfmpy(Rss32,Rtt32)",ATTRIBS(),
+ "Vector Floating-Point Fused Multiply Subtract",
+{
+ fSETWORD(0,RxxV,fUNFLOAT(fFMAF(-fFLOAT(fGETUWORD(0,RssV)),
+ fFLOAT(fGETUWORD(0,RttV)),
+ fFLOAT(fGETUWORD(0,RxxV)))));
+ fSETWORD(1,RxxV,fUNFLOAT(fFMAF(-fFLOAT(fGETUWORD(1,RssV)),
+ fFLOAT(fGETUWORD(1,RttV)),
+ fFLOAT(fGETUWORD(1,RxxV)))));
+})
+
Q6INSN(F2_sffma_lib,"Rx32+=sfmpy(Rs32,Rt32):lib",ATTRIBS(),
"Floating-Point Fused Multiply Add for Library Routines",
{ fFPSETROUND_NEAREST(); fHIDE(int infinp; int infminusinf; size4s_t tmp;)
--
2.34.1