Signed-off-by: Brian Cain <[email protected]>
---
target/hexagon/mmvec/hvx_ieee_fp.h | 2 +
target/hexagon/mmvec/macros.h | 2 +
target/hexagon/mmvec/hvx_ieee_fp.c | 15 ++++
target/hexagon/tag_rev_info.c.inc | 13 ++++
target/hexagon/imported/mmvec/encode_ext.def | 10 +++
target/hexagon/imported/mmvec/ext.idef | 74 ++++++++++++++++++++
6 files changed, 116 insertions(+)
diff --git a/target/hexagon/mmvec/hvx_ieee_fp.h
b/target/hexagon/mmvec/hvx_ieee_fp.h
index b7e379b0893..f7ea0086683 100644
--- a/target/hexagon/mmvec/hvx_ieee_fp.h
+++ b/target/hexagon/mmvec/hvx_ieee_fp.h
@@ -31,6 +31,8 @@ int16_t conv_h_hf(float16 a, float_status *fp_status);
/* IEEE - FP compare instructions */
uint32_t cmpgt_sf(float32 a1, float32 a2, float_status *fp_status);
uint16_t cmpgt_hf(float16 a1, float16 a2, float_status *fp_status);
+uint32_t cmpeq_sf(float32 a1, float32 a2, float_status *fp_status);
+uint16_t cmpeq_hf(float16 a1, float16 a2, float_status *fp_status);
/* IEEE BFloat instructions */
diff --git a/target/hexagon/mmvec/macros.h b/target/hexagon/mmvec/macros.h
index 4ac53aca0b9..74c277fc06f 100644
--- a/target/hexagon/mmvec/macros.h
+++ b/target/hexagon/mmvec/macros.h
@@ -383,5 +383,7 @@
#define fCMPGT_SF(A, B) cmpgt_sf(A, B, &env->hvx_fp_status)
#define fCMPGT_HF(A, B) cmpgt_hf(A, B, &env->hvx_fp_status)
#define fCMPGT_BF(A, B) fCMPGT_SF((uint32_t)(A) << 16, (uint32_t)(B) << 16)
+#define fCMPEQ_SF(A, B) cmpeq_sf(A, B, &env->hvx_fp_status)
+#define fCMPEQ_HF(A, B) cmpeq_hf(A, B, &env->hvx_fp_status)
#endif
diff --git a/target/hexagon/mmvec/hvx_ieee_fp.c
b/target/hexagon/mmvec/hvx_ieee_fp.c
index d7751adbe29..230ea9a13a7 100644
--- a/target/hexagon/mmvec/hvx_ieee_fp.c
+++ b/target/hexagon/mmvec/hvx_ieee_fp.c
@@ -135,3 +135,18 @@ uint16_t cmpgt_hf(float16 a1, float16 a2, float_status
*fp_status)
}
return float16_compare(a1, a2, fp_status) == float_relation_greater;
}
+
+/*
+ * Unlike cmpgt_sf/cmpgt_hf, equality has no NaN-ordering convention to
+ * apply: per IEEE-754, a compare-equal predicate is quiet and always
+ * false when either operand is NaN.
+ */
+uint32_t cmpeq_sf(float32 a1, float32 a2, float_status *fp_status)
+{
+ return float32_eq_quiet(a1, a2, fp_status);
+}
+
+uint16_t cmpeq_hf(float16 a1, float16 a2, float_status *fp_status)
+{
+ return float16_eq_quiet(a1, a2, fp_status);
+}
diff --git a/target/hexagon/tag_rev_info.c.inc
b/target/hexagon/tag_rev_info.c.inc
index 68be8cbafb2..c12896cd6c7 100644
--- a/target/hexagon/tag_rev_info.c.inc
+++ b/target/hexagon/tag_rev_info.c.inc
@@ -644,6 +644,19 @@ static const struct tag_rev_info
tag_rev_info[XX_LAST_OPCODE] = {
[Y2_dczeroa_nt] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE },
[Y2_tlbpp] = { .introduced = HEX_VER_V81, .removed = HEX_VER_NONE },
+
+ [V6_valign4] = { .introduced = HEX_VER_V81, .removed = HEX_VER_NONE },
+ [V6_veqhf] = { .introduced = HEX_VER_V81, .removed = HEX_VER_NONE },
+ [V6_veqhf_and] = { .introduced = HEX_VER_V81, .removed = HEX_VER_NONE },
+ [V6_veqhf_or] = { .introduced = HEX_VER_V81, .removed = HEX_VER_NONE },
+ [V6_veqhf_xor] = { .introduced = HEX_VER_V81, .removed = HEX_VER_NONE },
+ [V6_veqsf] = { .introduced = HEX_VER_V81, .removed = HEX_VER_NONE },
+ [V6_veqsf_and] = { .introduced = HEX_VER_V81, .removed = HEX_VER_NONE },
+ [V6_veqsf_or] = { .introduced = HEX_VER_V81, .removed = HEX_VER_NONE },
+ [V6_veqsf_xor] = { .introduced = HEX_VER_V81, .removed = HEX_VER_NONE },
+ [V6_vconv_h_hf_rnd] = {
+ .introduced = HEX_VER_V81, .removed = HEX_VER_NONE
+ },
};
#endif /* HEXAGON_TAG_ARCH_TABLE_H */
diff --git a/target/hexagon/imported/mmvec/encode_ext.def
b/target/hexagon/imported/mmvec/encode_ext.def
index 16f043b77dc..084ae3d8542 100644
--- a/target/hexagon/imported/mmvec/encode_ext.def
+++ b/target/hexagon/imported/mmvec/encode_ext.def
@@ -694,6 +694,7 @@ DEF_ENC(V6_vassign, ICLASS_CJ" 1 110 --0 ---11
PP 1 uuuuu 111 ddddd")
DEF_ENC(V6_valignbi, ICLASS_CJ" 1 110 001 vvvvv PP 1 uuuuu iii ddddd")
DEF_ENC(V6_vlalignbi, ICLASS_CJ" 1 110 011 vvvvv PP 1 uuuuu iii ddddd")
+DEF_ENC(V6_valign4,"00011000vvvvvtttPP0uuuuu101ddddd")
DEF_ENC(V6_vswap, ICLASS_CJ" 1 110 101 vvvvv PP 1 uuuuu -tt
ddddd") //
DEF_ENC(V6_vmux, ICLASS_CJ" 1 110 111 vvvvv PP 1 uuuuu -tt ddddd")
//
@@ -857,6 +858,7 @@ DEF_ENC(V6_vconv_sf_w,"00011110--0--101PP1uuuuu011ddddd")
DEF_ENC(V6_vconv_w_sf,"00011110--0--101PP1uuuuu001ddddd")
DEF_ENC(V6_vconv_hf_h,"00011110--0--101PP1uuuuu100ddddd")
DEF_ENC(V6_vconv_h_hf,"00011110--0--101PP1uuuuu010ddddd")
+DEF_ENC(V6_vconv_h_hf_rnd,"00011110--0-0110PP1uuuuu110ddddd")
/* IEEE FP compare instructions */
DEF_ENC(V6_vgtsf,"00011100100vvvvvPP1uuuuu011100dd")
@@ -867,6 +869,14 @@ DEF_ENC(V6_vgtsf_or,"00011100100vvvvvPP1uuuuu001100xx")
DEF_ENC(V6_vgthf_or,"00011100100vvvvvPP1uuuuu001101xx")
DEF_ENC(V6_vgtsf_xor,"00011100100vvvvvPP1uuuuu111010xx")
DEF_ENC(V6_vgthf_xor,"00011100100vvvvvPP1uuuuu111011xx")
+DEF_ENC(V6_veqsf,"00011111100vvvvvPP0uuuuu000011dd")
+DEF_ENC(V6_veqhf,"00011111100vvvvvPP0uuuuu000111dd")
+DEF_ENC(V6_veqsf_and,"00011100100vvvvvPP1uuuuu000011xx")
+DEF_ENC(V6_veqhf_and,"00011100100vvvvvPP1uuuuu000111xx")
+DEF_ENC(V6_veqsf_or,"00011100100vvvvvPP1uuuuu010011xx")
+DEF_ENC(V6_veqhf_or,"00011100100vvvvvPP1uuuuu010111xx")
+DEF_ENC(V6_veqsf_xor,"00011100100vvvvvPP1uuuuu100011xx")
+DEF_ENC(V6_veqhf_xor,"00011100100vvvvvPP1uuuuu100111xx")
/* BFLOAT instructions */
DEF_ENC(V6_vmpy_sf_bf,"00011101010vvvvvPP1uuuuu100ddddd")
diff --git a/target/hexagon/imported/mmvec/ext.idef
b/target/hexagon/imported/mmvec/ext.idef
index 857aa6133f8..e5998768b14 100644
--- a/target/hexagon/imported/mmvec/ext.idef
+++ b/target/hexagon/imported/mmvec/ext.idef
@@ -367,6 +367,18 @@ EXTINSN(V6_vlalignbi,"Vd32=vlalign(Vu32,Vv32,#u3)",
ATTRIBS(A_EXTENSION,A_CVI,A_
VALIGNB(shift)
})
+EXTINSN(V6_valign4, "Vd32=valign4(Vu32,Vv32,Rt8)",
+ ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VA,A_CVI_VA_2SRC),
+ "In-lane align two vectors by Rt8 as control",
+{
+ fHIDE(int i;)
+ fVFOREACH(32, i) {
+ unsigned shift = 8 * (RtV & 0x3);
+ VdV.uw[i] = shift ? (VuV.uw[i] << shift) | (VvV.uw[i] >> (32 - shift))
+ : VuV.uw[i];
+ }
+})
+
EXTINSN(V6_vror, "Vd32=vror(Vu32,Rt32)", ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VP),
"Align Two vectors by Rt32 as control",
{
@@ -3135,6 +3147,11 @@ ITERATOR_INSN_SHIFT_SLOT_FLT(16,
vconv_h_hf,"Vd32.h=Vu32.hf",
"Vector conversion of hf16 format to int hw",
VdV.h[i] = conv_h_hf(VuV.hf[i], &env->hvx_fp_status))
+ITERATOR_INSN_SHIFT_SLOT_FLT(16, vconv_h_hf_rnd,"Vd32.h=Vu32.hf:rnd",
+ "Vector conversion of hf16 format to int hw, round to nearest even",
+ VdV.h[i] = float16_to_int16_scalbn(VuV.hf[i], float_round_nearest_even, 0,
+ &env->hvx_fp_status))
+
ITERATOR_INSN_SHIFT_SLOT_FLT(32, vconv_sf_w,"Vd32.sf=Vu32.w",
"Vector conversion of int w format to sf32",
VdV.sf[i] = int32_to_float32(VuV.w[i], &env->hvx_fp_status))
@@ -3233,6 +3250,63 @@ MMVEC_CMPGT_SF(sf,"sf","Vector sf Compare ", fVELEM(32),
0xF, 4, sf)
MMVEC_CMPGT_HF(hf,"hf","Vector hf Compare ", fVELEM(16), 0x3, 2, hf)
MMVEC_CMPGT_BF(bf,"bf","Vector bf Compare ", fVELEM(16), 0x3, 2, bf)
+#define VCMPEQ_SF(DEST, ASRC, ASRCOP, CMP, N, SRC, MASK, WIDTH) \
+{ \
+ for (fHIDE(int) i = 0; i < fVBYTES(); i += WIDTH) { \
+ fHIDE(int) VAL = fCMPEQ_SF(VuV.SRC[i/WIDTH],VvV.SRC[i/WIDTH]) ? MASK :
0; \
+ fSETQBITS(DEST,WIDTH,MASK,i,ASRC ASRCOP VAL); \
+ } \
+}
+
+#define VCMPEQ_HF(DEST, ASRC, ASRCOP, CMP, N, SRC, MASK, WIDTH) \
+{ \
+ for (fHIDE(int) i = 0; i < fVBYTES(); i += WIDTH) { \
+ fHIDE(int) VAL = fCMPEQ_HF(VuV.SRC[i/WIDTH],VvV.SRC[i/WIDTH]) ? MASK :
0; \
+ fSETQBITS(DEST,WIDTH,MASK,i,ASRC ASRCOP VAL); \
+ } \
+}
+
+/* Vector SF compare equal */
+#define MMVEC_CMPEQ_SF(TYPE,TYPE2,DESCR,N,MASK,WIDTH,SRC) \
+ EXTINSN(V6_veq##TYPE##_and, "Qx4&=vcmp.eq(Vu32." TYPE2 ",Vv32." TYPE2 ")",
\
+ ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VA,A_CVI_VA_2SRC,A_HVX_FLT), \
+ DESCR" equal to with predicate-and", \
+ VCMPEQ_SF(QxV, fGETQBITS(QxV,WIDTH,MASK,i), &, "==", N, SRC, MASK,
WIDTH)) \
+ EXTINSN(V6_veq##TYPE##_xor, "Qx4^=vcmp.eq(Vu32." TYPE2 ",Vv32." TYPE2 ")",
\
+ ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VA,A_CVI_VA_2SRC,A_HVX_FLT), \
+ DESCR" equal to with predicate-xor", \
+ VCMPEQ_SF(QxV, fGETQBITS(QxV,WIDTH,MASK,i), ^, "==", N, SRC, MASK,
WIDTH)) \
+ EXTINSN(V6_veq##TYPE##_or, "Qx4|=vcmp.eq(Vu32." TYPE2 ",Vv32." TYPE2 ")", \
+ ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VA,A_CVI_VA_2SRC,A_HVX_FLT), \
+ DESCR" equal to with predicate-or", \
+ VCMPEQ_SF(QxV, fGETQBITS(QxV,WIDTH,MASK,i), |, "==", N, SRC, MASK,
WIDTH)) \
+ EXTINSN(V6_veq##TYPE, "Qd4=vcmp.eq(Vu32." TYPE2 ",Vv32." TYPE2 ")", \
+ ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VA,A_CVI_VA_2SRC,A_HVX_FLT), \
+ DESCR" equal to", \
+ VCMPEQ_SF(QdV, , , "==", N, SRC, MASK, WIDTH))
+
+/* Vector HF compare equal */
+#define MMVEC_CMPEQ_HF(TYPE,TYPE2,DESCR,N,MASK,WIDTH,SRC) \
+ EXTINSN(V6_veq##TYPE##_and, "Qx4&=vcmp.eq(Vu32." TYPE2 ",Vv32." TYPE2 ")",
\
+ ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VA,A_CVI_VA_2SRC,A_HVX_FLT), \
+ DESCR" equal to with predicate-and", \
+ VCMPEQ_HF(QxV, fGETQBITS(QxV,WIDTH,MASK,i), &, "==", N, SRC, MASK,
WIDTH)) \
+ EXTINSN(V6_veq##TYPE##_xor, "Qx4^=vcmp.eq(Vu32." TYPE2 ",Vv32." TYPE2 ")",
\
+ ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VA,A_CVI_VA_2SRC,A_HVX_FLT), \
+ DESCR" equal to with predicate-xor", \
+ VCMPEQ_HF(QxV, fGETQBITS(QxV,WIDTH,MASK,i), ^, "==", N, SRC, MASK,
WIDTH)) \
+ EXTINSN(V6_veq##TYPE##_or, "Qx4|=vcmp.eq(Vu32." TYPE2 ",Vv32." TYPE2 ")", \
+ ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VA,A_CVI_VA_2SRC,A_HVX_FLT), \
+ DESCR" equal to with predicate-or", \
+ VCMPEQ_HF(QxV, fGETQBITS(QxV,WIDTH,MASK,i), |, "==", N, SRC, MASK,
WIDTH)) \
+ EXTINSN(V6_veq##TYPE, "Qd4=vcmp.eq(Vu32." TYPE2 ",Vv32." TYPE2 ")", \
+ ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VA,A_CVI_VA_2SRC,A_HVX_FLT), \
+ DESCR" equal to", \
+ VCMPEQ_HF(QdV, , , "==", N, SRC, MASK, WIDTH))
+
+MMVEC_CMPEQ_SF(sf,"sf","Vector sf Compare ", fVELEM(32), 0xF, 4, sf)
+MMVEC_CMPEQ_HF(hf,"hf","Vector hf Compare ", fVELEM(16), 0x3, 2, hf)
+
/******************************************************************************
BFloat arithmetic and max/min instructions
******************************************************************************/
--
2.34.1