Reviewed-by: Marco Liebel <[email protected]>
Signed-off-by: Brian Cain <[email protected]>
---
target/hexagon/mmvec/macros.h | 109 +++++++++++++
target/hexagon/mmvec/mmvec.h | 35 ++++
target/hexagon/tag_rev_info.c.inc | 41 +++++
target/hexagon/imported/mmvec/encode_ext.def | 51 ++++++
target/hexagon/imported/mmvec/ext.idef | 162 +++++++++++++++++++
5 files changed, 398 insertions(+)
diff --git a/target/hexagon/mmvec/macros.h b/target/hexagon/mmvec/macros.h
index 2bf360dd2c1..5339f748e3f 100644
--- a/target/hexagon/mmvec/macros.h
+++ b/target/hexagon/mmvec/macros.h
@@ -24,6 +24,7 @@
#include "accel/tcg/getpc.h"
#include "accel/tcg/probe.h"
#include "mmvec/hvx_ieee_fp.h"
+#include "mmvec/mmvec_qfloat.h"
#define fBFLOAT()
#define fCVI_VX_NO_TMP_LD()
@@ -386,4 +387,112 @@
#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)
+/*
+ * qfloat extended-precision bits: {G,S}ET_VEXT access a vector element's
+ * ext; f{G,S}ETQFEXT_BIT view that storage as one raw bit per source byte,
+ * for the v{g,s}etqfext.
+ */
+#define GET_VEXT(VSRC, IDX, SIZE) get_extended_bits(&(VSRC), IDX, SIZE)
+#define SET_VEXT(VDEST, IDX, SIZE, VAL) \
+ set_extended_bits(&(VDEST), IDX, SIZE, VAL)
+#define GET_VEXT_PAIR(VSRC, PAIR_IDX, IDX, SIZE) \
+ get_extended_bits(&(VSRC).v[PAIR_IDX], IDX, SIZE)
+
+#define fGETQFEXT_BIT(REG, BITNO) \
+ (0x1 & ((REG).ext[(BITNO) / 4] >> ((BITNO) % 4)))
+#define fSETQFEXT_BIT(REG, BITNO, VAL) \
+ do { \
+ uint32_t bitno_val = (VAL); \
+ (REG).ext[(BITNO) / 4] &= ~(1 << ((BITNO) % 4)); \
+ (REG).ext[(BITNO) / 4] |= (bitno_val & 1) << ((BITNO) % 4); \
+ } while (0)
+
+#define fPARSEHF(A) parse_hf(A)
+#define fPARSESF(A) parse_sf_daz(A, is_daz_mode(env))
+#define fPARSEQF_EXT(SIZE, A, IDX) \
+ (qfloat_is_extended(env) ? \
+ parse_extqf##SIZE((A).qf##SIZE[IDX], \
+ get_extended_bits(&(A), IDX, SIZE)) : \
+ legacy_parse_qf##SIZE((A).qf##SIZE[IDX]))
+
+#define fQF_VILOG2(TYPE, A, AEXT) qf_vilog2(TYPE, A, AEXT)
+
+#define fCONVERT_QF32_TO_SF(A, AEXT) \
+ (qfloat_is_extended(env) ? \
+ conv_sf_extqf32(A, AEXT, CVI_QFRND_MODE) : legacy_conv_sf_qf32(A))
+#define fCONVERT_QF32_TO_HF(A, AEXT) \
+ (qfloat_is_extended(env) ? \
+ conv_hf_extqf32(A, AEXT, CVI_QFRND_MODE) : legacy_conv_hf_qf32(A))
+#define fCONVERT_QF32_TO_BF(A, AEXT) conv_qf32_to_bf(A, AEXT, CVI_QFRND_MODE)
+#define fCONVERT_QF16_TO_HF(A, AEXT) \
+ (qfloat_is_extended(env) ? \
+ conv_hf_extqf16(A, AEXT, CVI_QFRND_MODE) : legacy_conv_hf_qf16(A))
+
+/*
+ * Add/multiply two qfloat operands in the extended-precision "unfloat"
+ * domain and round+pack the result back into V.qf{16,32}[i] / V's ext bits
+ * at index i.
+ */
+#define fQFADD(SIZE, V, A, B) \
+ do { \
+ if (!qfloat_is_extended(env)) { \
+ (V).qf##SIZE[i] = legacy_qf_add(SIZE, A, B); \
+ } else if ((A).inf || (A).nan || (B).inf || (B).nan) { \
+ uint64_t sig_36 = handle_infinity_nan_add((A), (B), \
+ extqf##SIZE##_pos_nan, extqf##SIZE##_neg_nan, \
+ extqf##SIZE##_pos_inf, extqf##SIZE##_neg_inf); \
+ (V).qf##SIZE[i] = sig_36 >> 4; \
+ set_extended_bits(&(V), i, SIZE, sig_36 & EXT##SIZE##_BITMASK); \
+ } else { \
+ FloatParts64 pa = qfloat_unfloat_parts(A); \
+ FloatParts64 pb = qfloat_unfloat_parts(B); \
+ float_status status = { 0 }; \
+ int sub = pa.sign ^ pb.sign; \
+ int rexp; \
+ if (pa.cls == float_class_zero) { \
+ rexp = (B).exp; \
+ } else if (pb.cls == float_class_zero) { \
+ rexp = (A).exp; \
+ } else if ((A).exp > (B).exp) { \
+ rexp = MAX(pa.exp - sub, (B).exp); \
+ } else { \
+ rexp = MAX(pb.exp - sub, (A).exp); \
+ } \
+ FloatParts64 pr = parts64_addsub(&pa, &pb, \
+ &status, false); \
+ uint64_t result = qfloat_round_ext_parts(SIZE, pr, rexp, \
+ (A).sign && (B).sign, \
+ CVI_QFRND_MODE); \
+ (V).qf##SIZE[i] = (result >> (SIZE / 8)) & QF##SIZE##_BITMASK; \
+ set_extended_bits(&(V), i, SIZE, result & EXT##SIZE##_BITMASK); \
+ } \
+ } while (0)
+
+#define fQFMPY(SIZE, V, A, B) \
+ do { \
+ if (!qfloat_is_extended(env)) { \
+ (V).qf##SIZE[i] = legacy_qf_mpy(SIZE, A, B); \
+ } else if ((A).inf || (A).nan || (B).inf || (B).nan) { \
+ uint64_t sig_36 = handle_infinity_nan_mpy((A), (B), \
+ extqf##SIZE##_pos_nan, extqf##SIZE##_neg_nan, \
+ extqf##SIZE##_pos_inf, extqf##SIZE##_neg_inf); \
+ (V).qf##SIZE[i] = sig_36 >> 4; \
+ set_extended_bits(&(V), i, SIZE, sig_36 & EXT##SIZE##_BITMASK); \
+ } else { \
+ FloatParts64 pa = qfloat_unfloat_parts(A); \
+ FloatParts64 pb = qfloat_unfloat_parts(B); \
+ float_status status = { 0 }; \
+ int rexp = (A).exp + (B).exp; \
+ bool defer = (A).sign ^ (B).sign ^ (A).parts.sign ^ \
+ (B).parts.sign ^ \
+ ((A).parts.sign && (B).parts.sign); \
+ FloatParts64 pr = parts64_mul(&pa, &pb, &status); \
+ uint64_t result = qfloat_round_ext_parts(SIZE, pr, rexp, \
+ defer, \
+ CVI_QFRND_MODE); \
+ (V).qf##SIZE[i] = (result >> (SIZE / 8)) & QF##SIZE##_BITMASK; \
+ set_extended_bits(&(V), i, SIZE, result & EXT##SIZE##_BITMASK); \
+ } \
+ } while (0)
+
#endif
diff --git a/target/hexagon/mmvec/mmvec.h b/target/hexagon/mmvec/mmvec.h
index 462d66b686b..0309a70a8f5 100644
--- a/target/hexagon/mmvec/mmvec.h
+++ b/target/hexagon/mmvec/mmvec.h
@@ -56,6 +56,9 @@ typedef struct {
float32 sf[MAX_VEC_SIZE_BYTES / 4];
float16 hf[MAX_VEC_SIZE_BYTES / 2];
bfloat16 bf[MAX_VEC_SIZE_BYTES / 2];
+ /* qfloat "visible" mantissa/exponent, sans the extended bits below */
+ int32_t qf32[MAX_VEC_SIZE_BYTES / 4];
+ int16_t qf16[MAX_VEC_SIZE_BYTES / 2];
};
/*
* Extended precision bits for qfloat: one byte per qf32 element (only
@@ -72,6 +75,38 @@ typedef struct {
MMVector v[2];
} MMVectorPair;
+/*
+ * val is expected to already be masked to the width of the extended-bits
+ * field being written (1 bit for a qf32 element, 2 bits for a qf16
+ * element); size selects which.
+ */
+static inline void set_extended_bits(MMVector *v, int i, int size, uint8_t val)
+{
+ if (size == 32) {
+ v->ext[i] = val;
+ } else {
+ /* Two qf16 elements share an ext byte: low 2 bits, then high 2 */
+ if (i % 2 == 1) {
+ v->ext[i / 2] = ((val & 0x3) << 2) | (v->ext[i / 2] & 0x3);
+ } else {
+ v->ext[i / 2] = (v->ext[i / 2] & 0xc) | (val & 0x3);
+ }
+ }
+}
+
+static inline uint8_t get_extended_bits(const MMVector *v, int i, int size)
+{
+ if (size == 32) {
+ return v->ext[i];
+ } else {
+ if (i % 2 == 1) {
+ return (v->ext[i / 2] >> 2) & 0x3;
+ } else {
+ return v->ext[i / 2] & 0x3;
+ }
+ }
+}
+
typedef union {
uint64_t ud[MAX_VEC_SIZE_BYTES / 8 / 8];
int64_t d[MAX_VEC_SIZE_BYTES / 8 / 8];
diff --git a/target/hexagon/tag_rev_info.c.inc
b/target/hexagon/tag_rev_info.c.inc
index c12896cd6c7..41ce3cb572f 100644
--- a/target/hexagon/tag_rev_info.c.inc
+++ b/target/hexagon/tag_rev_info.c.inc
@@ -657,6 +657,47 @@ static const struct tag_rev_info
tag_rev_info[XX_LAST_OPCODE] = {
[V6_vconv_h_hf_rnd] = {
.introduced = HEX_VER_V81, .removed = HEX_VER_NONE
},
+
+ [V6_get_qfext] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE },
+ [V6_get_qfext_oracc] = {
+ .introduced = HEX_VER_V79, .removed = HEX_VER_NONE
+ },
+ [V6_set_qfext] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE },
+ [V6_vabs_qf16_hf] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE },
+ [V6_vabs_qf16_qf16] = {
+ .introduced = HEX_VER_V79, .removed = HEX_VER_NONE
+ },
+ [V6_vabs_qf32_qf32] = {
+ .introduced = HEX_VER_V79, .removed = HEX_VER_NONE
+ },
+ [V6_vabs_qf32_sf] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE },
+ [V6_vconv_bf_qf32] = { .introduced = HEX_VER_V81, .removed = HEX_VER_NONE
},
+ [V6_vconv_qf16_hf] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE
},
+ [V6_vconv_qf16_qf16] = {
+ .introduced = HEX_VER_V79, .removed = HEX_VER_NONE
+ },
+ [V6_vconv_qf32_qf32] = {
+ .introduced = HEX_VER_V79, .removed = HEX_VER_NONE
+ },
+ [V6_vconv_qf32_sf] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE
},
+ [V6_vilog2_hf] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE },
+ [V6_vilog2_qf16] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE },
+ [V6_vilog2_qf32] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE },
+ [V6_vilog2_sf] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE },
+ [V6_vmerge_qf] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE },
+ [V6_vmpy_rt_hf] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE },
+ [V6_vmpy_rt_qf16] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE },
+ [V6_vmpy_rt_sf] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE },
+ [V6_vneg_qf16_hf] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE },
+ [V6_vneg_qf16_qf16] = {
+ .introduced = HEX_VER_V79, .removed = HEX_VER_NONE
+ },
+ [V6_vneg_qf32_qf32] = {
+ .introduced = HEX_VER_V79, .removed = HEX_VER_NONE
+ },
+ [V6_vneg_qf32_sf] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE },
+ [V6_vsub_hf_mix] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE },
+ [V6_vsub_sf_mix] = { .introduced = HEX_VER_V79, .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 b46f51492d9..34e63b89743 100644
--- a/target/hexagon/imported/mmvec/encode_ext.def
+++ b/target/hexagon/imported/mmvec/encode_ext.def
@@ -893,4 +893,55 @@ DEF_ENC(V6_vgtbf_and,"00011100100vvvvvPP1uuuuu110100xx")
DEF_ENC(V6_vgtbf_or,"00011100100vvvvvPP1uuuuu001110xx")
DEF_ENC(V6_vgtbf_xor,"00011100100vvvvvPP1uuuuu111100xx")
+/* QFloat extended-precision instructions */
+DEF_ENC(V6_get_qfext,"00011001110tttttPP0uuuuu111ddddd")
+DEF_ENC(V6_get_qfext_oracc,"00011001110tttttPP0uuuuu110xxxxx")
+DEF_ENC(V6_set_qfext,"00011001110tttttPP0uuuuu011ddddd")
+DEF_ENC(V6_vmerge_qf,"00011111000vvvvvPP1uuuuu111ddddd")
+DEF_ENC(V6_vabs_qf16_hf,"00011110--0-1110PP1uuuuu110ddddd")
+DEF_ENC(V6_vabs_qf16_qf16,"00011110--0-1110PP1uuuuu111ddddd")
+DEF_ENC(V6_vabs_qf32_qf32,"00011110--0-1110PP1uuuuu101ddddd")
+DEF_ENC(V6_vabs_qf32_sf,"00011110--0-1110PP1uuuuu100ddddd")
+DEF_ENC(V6_vadd_hf,"00011111011vvvvvPP1uuuuu011ddddd")
+DEF_ENC(V6_vadd_qf16,"00011111011vvvvvPP1uuuuu010ddddd")
+DEF_ENC(V6_vadd_qf16_mix,"00011111011vvvvvPP1uuuuu100ddddd")
+DEF_ENC(V6_vadd_qf32,"00011111101vvvvvPP1uuuuu000ddddd")
+DEF_ENC(V6_vadd_qf32_mix,"00011111101vvvvvPP1uuuuu010ddddd")
+DEF_ENC(V6_vadd_sf,"00011111101vvvvvPP1uuuuu001ddddd")
+DEF_ENC(V6_vconv_bf_qf32,"00011110--0-0110PP1uuuuu111ddddd")
+DEF_ENC(V6_vconv_hf_qf16,"00011110--0-0100PP1uuuuu011ddddd")
+DEF_ENC(V6_vconv_hf_qf32,"00011110--0-0100PP1uuuuu110ddddd")
+DEF_ENC(V6_vconv_qf16_hf,"00011110--0-1100PP1uuuuu100ddddd")
+DEF_ENC(V6_vconv_qf16_qf16,"00011110--0-1100PP1uuuuu110ddddd")
+DEF_ENC(V6_vconv_qf32_qf32,"00011110--0-1101PP1uuuuu111ddddd")
+DEF_ENC(V6_vconv_qf32_sf,"00011110--0-1101PP1uuuuu110ddddd")
+DEF_ENC(V6_vconv_sf_qf32,"00011110--0-0100PP1uuuuu000ddddd")
+DEF_ENC(V6_vilog2_hf,"00011110--0-1100PP1uuuuu011ddddd")
+DEF_ENC(V6_vilog2_qf16,"00011110--0-1100PP1uuuuu001ddddd")
+DEF_ENC(V6_vilog2_qf32,"00011110--0-1100PP1uuuuu000ddddd")
+DEF_ENC(V6_vilog2_sf,"00011110--0-1100PP1uuuuu010ddddd")
+DEF_ENC(V6_vmpy_qf16,"00011111111vvvvvPP1uuuuu011ddddd")
+DEF_ENC(V6_vmpy_qf16_hf,"00011111111vvvvvPP1uuuuu100ddddd")
+DEF_ENC(V6_vmpy_qf16_mix_hf,"00011111111vvvvvPP1uuuuu101ddddd")
+DEF_ENC(V6_vmpy_qf32,"00011111111vvvvvPP1uuuuu000ddddd")
+DEF_ENC(V6_vmpy_qf32_hf,"00011111111vvvvvPP1uuuuu111ddddd")
+DEF_ENC(V6_vmpy_qf32_mix_hf,"00011111100vvvvvPP1uuuuu000ddddd")
+DEF_ENC(V6_vmpy_qf32_qf16,"00011111111vvvvvPP1uuuuu110ddddd")
+DEF_ENC(V6_vmpy_qf32_sf,"00011111111vvvvvPP1uuuuu001ddddd")
+DEF_ENC(V6_vmpy_rt_hf,"00011010000tttttPP1uuuuu011ddddd")
+DEF_ENC(V6_vmpy_rt_qf16,"00011010000tttttPP1uuuuu010ddddd")
+DEF_ENC(V6_vmpy_rt_sf,"00011010000tttttPP1uuuuu001ddddd")
+DEF_ENC(V6_vneg_qf16_hf,"00011110--0-1110PP1uuuuu010ddddd")
+DEF_ENC(V6_vneg_qf16_qf16,"00011110--0-1110PP1uuuuu011ddddd")
+DEF_ENC(V6_vneg_qf32_qf32,"00011110--0-1110PP1uuuuu001ddddd")
+DEF_ENC(V6_vneg_qf32_sf,"00011110--0-1110PP1uuuuu000ddddd")
+DEF_ENC(V6_vsub_hf,"00011111011vvvvvPP1uuuuu110ddddd")
+DEF_ENC(V6_vsub_hf_mix,"00011010000vvvvvPP1uuuuu100ddddd")
+DEF_ENC(V6_vsub_qf16,"00011111011vvvvvPP1uuuuu101ddddd")
+DEF_ENC(V6_vsub_qf16_mix,"00011111011vvvvvPP1uuuuu111ddddd")
+DEF_ENC(V6_vsub_qf32,"00011111101vvvvvPP1uuuuu011ddddd")
+DEF_ENC(V6_vsub_qf32_mix,"00011111101vvvvvPP1uuuuu101ddddd")
+DEF_ENC(V6_vsub_sf,"00011111101vvvvvPP1uuuuu100ddddd")
+DEF_ENC(V6_vsub_sf_mix,"00011010000vvvvvPP1uuuuu000ddddd")
+
#endif /* NO MMVEC */
diff --git a/target/hexagon/imported/mmvec/ext.idef
b/target/hexagon/imported/mmvec/ext.idef
index 77fd1c61017..3592930777e 100644
--- a/target/hexagon/imported/mmvec/ext.idef
+++ b/target/hexagon/imported/mmvec/ext.idef
@@ -3339,6 +3339,168 @@ ITERATOR_INSN_IEEE_FP_16_32_LATE(16, vmin_bf,
"Vd32.bf=vmin(Vu32.bf,Vv32.bf)",
"Vector IEEE min: bf", VdV.bf[i] = fp_min_bf(VuV.bf[i], VvV.bf[i]);
fBFLOAT())
+
+/******************************************************************************
+ QFloat extended-precision instructions
+
******************************************************************************/
+
+EXTINSN(V6_get_qfext,"Vd32=vgetqfext(Vu32.x,Rt32)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VX,A_HVX_FLT),"Store
with extended bits of a vreg into QReg",
+{ fHIDE(int i;) fVFOREACH(8, i) { VdV.ub[i] = fGETQFEXT_BIT(VuV,i) ?
fGETUBYTE(i % 4, RtV) : 0; } })
+
+EXTINSN(V6_get_qfext_oracc,"Vx32|=vgetqfext(Vu32.x,Rt32)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VX,A_HVX_FLT),"Store
with extended bits of a vreg into QReg",
+{ fHIDE(int i;) fVFOREACH(8, i) { VxV.ub[i] |= fGETQFEXT_BIT(VuV,i) ?
fGETUBYTE(i % 4, RtV) : 0; } })
+
+EXTINSN(V6_set_qfext,"Vd32.x=vsetqfext(Vu32,Rt32)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VX,A_HVX_FLT),"Load
extended bits of Vreg using QReg",
+{
+ fHIDE(int i;)
+ fVFOREACH(8, i) {
+ /* Not explicitly stated at the spec, but this insn should clear the
main bits. */
+ VdV.ub[i] = 0;
+ fSETQFEXT_BIT(VdV,i,((VuV.ub[i] & fGETUBYTE(i % 4, RtV)) != 0) ? 1 :
0);
+ }
+})
+
+EXTINSN(V6_vmerge_qf,"Vd32=vmerge(Vu32.x,Vv32.w)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Merge
32 bit word and 4 bit extended bits",
+{ fHIDE(int i;) fVFOREACH(32, i) { VdV.uw[i] = VvV.uw[i];
SET_VEXT(VdV,i,32,GET_VEXT(VuV,i,32)); } })
+
+EXTINSN(V6_vabs_qf16_hf,"Vd32.qf16=vabs(Vu32.hf)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Convert
absolute value of hf to qf32",
+{ fHIDE(int i;) fVFOREACH(16, i) { fHIDE(unfloat )u = fPARSEHF(VuV.hf[i]);
if(is_unfloat_neg(u)) u.sign = !u.sign; INIT_UNFLOAT(v) v.exp = E_MIN_EXTQF16;
v.sign = 1; fQFADD(16,VdV,u,v) ; } })
+
+EXTINSN(V6_vabs_qf16_qf16,"Vd32.qf16=vabs(Vu32.qf16)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Normalize
absolute qf16 value",
+{ fHIDE(int i;) fVFOREACH(16, i) { fHIDE(unfloat )u = fPARSEQF_EXT(16,VuV,i);
if(is_unfloat_neg(u)) u.sign = !u.sign; INIT_UNFLOAT(v) v.exp = E_MIN_EXTQF16;
v.sign = 1; fQFADD(16,VdV,u,v) ; } })
+
+EXTINSN(V6_vabs_qf32_qf32,"Vd32.qf32=vabs(Vu32.qf32)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Normalize
absolute qf32 value",
+{ fHIDE(int i;) fVFOREACH(32, i) { fHIDE(unfloat )u = fPARSEQF_EXT(32,VuV,i);
if(is_unfloat_neg(u)) u.sign = !u.sign; INIT_UNFLOAT(v) v.exp = E_MIN_EXTQF32;
v.sign = 1; fQFADD(32,VdV,u,v) ; } })
+
+EXTINSN(V6_vabs_qf32_sf,"Vd32.qf32=vabs(Vu32.sf)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Convert
absolute value of sf to qf32",
+{ fHIDE(int i;) fVFOREACH(32, i) { fHIDE(unfloat )u = fPARSESF(VuV.sf[i]);
if(is_unfloat_neg(u)) u.sign = !u.sign; INIT_UNFLOAT(v) v.exp = E_MIN_EXTQF32;
v.sign = 1; fQFADD(32,VdV,u,v) ; } })
+
+EXTINSN(V6_vadd_hf,"Vd32.qf16=vadd(Vu32.hf,Vv32.hf)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Vector
addition of hf input",
+{ fHIDE(int i;) fVFOREACH(16, i) { fHIDE(unfloat )u = fPARSEHF(VuV.hf[i]);
fHIDE(unfloat )v = fPARSEHF(VvV.hf[i]); fQFADD(16,VdV,u,v) ; } })
+
+EXTINSN(V6_vadd_qf16,"Vd32.qf16=vadd(Vu32.qf16,Vv32.qf16)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Vector
addition of qf16 input",
+{ fHIDE(int i;) fVFOREACH(16, i) { fHIDE(unfloat )u = fPARSEQF_EXT(16,VuV,i);
fHIDE(unfloat )v = fPARSEQF_EXT(16,VvV,i); fQFADD(16,VdV,u,v) ; } })
+
+EXTINSN(V6_vadd_qf16_mix,"Vd32.qf16=vadd(Vu32.qf16,Vv32.hf)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Vector
addition of mixed qf16 and hf",
+{ fHIDE(int i;) fVFOREACH(16, i) { fHIDE(unfloat )u = fPARSEQF_EXT(16,VuV,i);
fHIDE(unfloat )v = fPARSEHF(VvV.hf[i]); fQFADD(16,VdV,u,v) ; } })
+
+EXTINSN(V6_vadd_qf32,"Vd32.qf32=vadd(Vu32.qf32,Vv32.qf32)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Vector
addition of qf32 input",
+{ fHIDE(int i;) fVFOREACH(32, i) { fHIDE(unfloat )u = fPARSEQF_EXT(32,VuV,i);
fHIDE(unfloat )v = fPARSEQF_EXT(32,VvV,i); fQFADD(32,VdV,u,v) ; } })
+
+EXTINSN(V6_vadd_qf32_mix,"Vd32.qf32=vadd(Vu32.qf32,Vv32.sf)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Vector
addition of mixed qf32 and sf",
+{ fHIDE(int i;) fVFOREACH(32, i) { fHIDE(unfloat )u = fPARSEQF_EXT(32,VuV,i);
fHIDE(unfloat )v = fPARSESF(VvV.sf[i]); fQFADD(32,VdV,u,v) ; } })
+
+EXTINSN(V6_vadd_sf,"Vd32.qf32=vadd(Vu32.sf,Vv32.sf)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Vector
addition of sf input",
+{ fHIDE(int i;) fVFOREACH(32, i) { fHIDE(unfloat )u = fPARSESF(VuV.sf[i]);
fHIDE(unfloat )v = fPARSESF(VvV.sf[i]); fQFADD(32,VdV,u,v) ; } })
+
+EXTINSN(V6_vconv_bf_qf32,"Vd32.bf=Vuu32.qf32",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Vector
conversion of double qf32 to BF",
+{ fHIDE(int i;) fVFOREACH(32, i) {
+ VdV.bf[2*i] = fCONVERT_QF32_TO_BF(VuuV.v[0].qf32[i],
GET_VEXT_PAIR(VuuV,0,i,32));
+ VdV.bf[2*i+1] = fCONVERT_QF32_TO_BF(VuuV.v[1].qf32[i],
GET_VEXT_PAIR(VuuV,1,i,32));
+} })
+
+EXTINSN(V6_vconv_hf_qf16,"Vd32.hf=Vu32.qf16",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Vector
conversion of qf16 format to ieee HF",
+{ fHIDE(int i;) fVFOREACH(16, i) { VdV.hf[i] =
fCONVERT_QF16_TO_HF(VuV.qf16[i],GET_VEXT(VuV,i,16)) ; } })
+
+EXTINSN(V6_vconv_hf_qf32,"Vd32.hf=Vuu32.qf32",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Vector
conversion of double qf32 to ieee HF",
+{ fHIDE(int i;) fVFOREACH(32, i) { VdV.hf[2*i] =
fCONVERT_QF32_TO_HF(VuuV.v[0].qf32[i], GET_VEXT_PAIR(VuuV,0,i,32));
VdV.hf[2*i+1] = fCONVERT_QF32_TO_HF(VuuV.v[1].qf32[i],
GET_VEXT_PAIR(VuuV,1,i,32)); } })
+
+EXTINSN(V6_vconv_qf16_hf,"Vd32.qf16=Vu32.hf",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Vector
conversion of qf16 format to ieee HF",
+{ fHIDE(int i;) fVFOREACH(16, i) { fHIDE(unfloat )u = fPARSEHF(VuV.hf[i]);
INIT_UNFLOAT(v) v.exp = E_MIN_EXTQF16; v.sign = 1; fQFADD(16,VdV,u,v) ; } })
+
+EXTINSN(V6_vconv_qf16_qf16,"Vd32.qf16=Vu32.qf16",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Vector
conversion of qf16 to qf16",
+{ fHIDE(int i;) fVFOREACH(16, i) { fHIDE(unfloat )u = fPARSEQF_EXT(16,VuV,i);
INIT_UNFLOAT(v) v.exp = E_MIN_EXTQF16; v.sign = 1; fQFADD(16,VdV,u,v) ; } })
+
+EXTINSN(V6_vconv_qf32_qf32,"Vd32.qf32=Vu32.qf32",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Normalize
qf32 value",
+{ fHIDE(int i;) fVFOREACH(32, i) { fHIDE(unfloat )u = fPARSEQF_EXT(32,VuV,i);
INIT_UNFLOAT(v) v.exp = E_MIN_EXTQF32; v.sign = 1; fQFADD(32,VdV,u,v) ; } })
+
+EXTINSN(V6_vconv_qf32_sf,"Vd32.qf32=Vu32.sf",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Vector
conversion of ieee SF to qf32",
+{ fHIDE(int i;) fVFOREACH(32, i) { fHIDE(unfloat )u = fPARSESF(VuV.sf[i]);
INIT_UNFLOAT(v) v.exp = E_MIN_EXTQF32; v.sign = 1; fQFADD(32,VdV,u,v) ; } })
+
+EXTINSN(V6_vconv_sf_qf32,"Vd32.sf=Vu32.qf32",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Vector
conversion of qf32 format to ieee SF",
+{ fHIDE(int i;) fVFOREACH(32, i) { VdV.sf[i] =
fCONVERT_QF32_TO_SF(VuV.qf32[i],GET_VEXT(VuV,i,32)) ; } })
+
+EXTINSN(V6_vilog2_hf,"Vd32.w=vilog2(Vu32.hf)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Exponent
extraction of hf",
+{ fHIDE(int i;) fVFOREACH(16, i) { VdV.h[i] = fQF_VILOG2(HF,VuV.hf[i],0) ; }
})
+
+EXTINSN(V6_vilog2_qf16,"Vd32.w=vilog2(Vu32.qf16)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Exponent
extraction of qf16",
+{ fHIDE(int i;) fVFOREACH(16, i) { VdV.h[i] =
fQF_VILOG2(EXTQF16,VuV.qf16[i],GET_VEXT(VuV,i,16)) ; } })
+
+EXTINSN(V6_vilog2_qf32,"Vd32.w=vilog2(Vu32.qf32)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Exponent
extraction of qf32",
+{ fHIDE(int i;) fVFOREACH(32, i) { VdV.w[i] =
fQF_VILOG2(EXTQF32,VuV.qf32[i],GET_VEXT(VuV,i,32)) ; } })
+
+EXTINSN(V6_vilog2_sf,"Vd32.w=vilog2(Vu32.sf)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Exponent
extraction of sf",
+{ fHIDE(int i;) fVFOREACH(32, i) { VdV.w[i] = fQF_VILOG2(SF,VuV.sf[i],0) ; }
})
+
+EXTINSN(V6_vmpy_qf16,"Vd32.qf16=vmpy(Vu32.qf16,Vv32.qf16)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VX_DV,A_HVX_FLT),"Vector
multiply: qf16 output from qf16 inupt",
+{ fHIDE(int i;) fVFOREACH(16, i) { fHIDE(unfloat )u = fPARSEQF_EXT(16,VuV,i);
fHIDE(unfloat )v = fPARSEQF_EXT(16,VvV,i); fQFMPY(16,VdV,u,v) ; } })
+
+EXTINSN(V6_vmpy_qf16_hf,"Vd32.qf16=vmpy(Vu32.hf,Vv32.hf)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VX_DV,A_HVX_FLT),"Vector
multiply: qf16 output from ieee hf input",
+{ fHIDE(int i;) fVFOREACH(16, i) { fHIDE(unfloat )u = fPARSEHF(VuV.hf[i]);
fHIDE(unfloat )v = fPARSEHF(VvV.hf[i]); fQFMPY(16,VdV,u,v) ; } })
+
+EXTINSN(V6_vmpy_qf16_mix_hf,"Vd32.qf16=vmpy(Vu32.qf16,Vv32.hf)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VX_DV,A_HVX_FLT),"Vector
multiply: qf16 output from mixed input of qf16 and ieee hf",
+{ fHIDE(int i;) fVFOREACH(16, i) { fHIDE(unfloat )u = fPARSEQF_EXT(16,VuV,i);
fHIDE(unfloat )v = fPARSEHF(VvV.hf[i]); fQFMPY(16,VdV,u,v) ; } })
+
+EXTINSN(V6_vmpy_qf32,"Vd32.qf32=vmpy(Vu32.qf32,Vv32.qf32)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VX_DV,A_HVX_FLT),"Vector
multiply: qf32 output from qf32 input",
+{ fHIDE(int i;) fVFOREACH(32, i) { fHIDE(unfloat )u = fPARSEQF_EXT(32,VuV,i);
fHIDE(unfloat )v = fPARSEQF_EXT(32,VvV,i); fQFMPY(32,VdV,u,v) ; } })
+
+EXTINSN(V6_vmpy_qf32_hf,"Vdd32.qf32=vmpy(Vu32.hf,Vv32.hf)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VX_DV,A_HVX_FLT),"Vector
multiply: double qf32 output from ieee hf input",
+{ fHIDE(int i;) fVFOREACH(32, i) { fHIDE(unfloat )u0 = fPARSEHF(VuV.w[i] &
0xFFFF); fHIDE(unfloat )u1 = fPARSEHF((VuV.w[i]>>16) & 0xFFFF); fHIDE(unfloat
)v0 = fPARSEHF(VvV.w[i] & 0xFFFF); fHIDE(unfloat )v1 = fPARSEHF((VvV.w[i]>>16)
& 0xFFFF); fQFMPY(32,VddV.v[0],u0,v0); fQFMPY(32,VddV.v[1],u1,v1) ; } })
+
+EXTINSN(V6_vmpy_qf32_mix_hf,"Vdd32.qf32=vmpy(Vu32.qf16,Vv32.hf)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VX_DV,A_HVX_FLT),"Vector
multiply: double qf32 output from mixed input of qf16 and ieee hf",
+{ fHIDE(int i;) fVFOREACH(32, i) { fHIDE(unfloat )u0 =
fPARSEQF_EXT(16,VuV,2*i); fHIDE(unfloat )u1 = fPARSEQF_EXT(16,VuV,2*i+1);
fHIDE(unfloat )v0 = fPARSEHF(VvV.w[i] & 0xFFFF); fHIDE(unfloat )v1 =
fPARSEHF((VvV.w[i]>>16) & 0xFFFF); fQFMPY(32,VddV.v[0],u0,v0);
fQFMPY(32,VddV.v[1],u1,v1) ; } })
+
+EXTINSN(V6_vmpy_qf32_qf16,"Vdd32.qf32=vmpy(Vu32.qf16,Vv32.qf16)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VX_DV,A_HVX_FLT),"Vector
multiply: double qf32 output from qf16 input",
+{ fHIDE(int i;) fVFOREACH(32, i) { fHIDE(unfloat )u0 =
fPARSEQF_EXT(16,VuV,2*i); fHIDE(unfloat )u1 = fPARSEQF_EXT(16,VuV,2*i+1);
fHIDE(unfloat )v0 = fPARSEQF_EXT(16,VvV,2*i); fHIDE(unfloat )v1 =
fPARSEQF_EXT(16,VvV,2*i+1); fQFMPY(32,VddV.v[0],u0,v0);
fQFMPY(32,VddV.v[1],u1,v1) ; } })
+
+EXTINSN(V6_vmpy_qf32_sf,"Vd32.qf32=vmpy(Vu32.sf,Vv32.sf)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VX_DV,A_HVX_FLT),"Vector
multiply: qf32 output from IEEE sf input",
+{ fHIDE(int i;) fVFOREACH(32, i) { fHIDE(unfloat )u = fPARSESF(VuV.sf[i]);
fHIDE(unfloat )v = fPARSESF(VvV.sf[i]); fQFMPY(32,VdV,u,v) ; } })
+
+EXTINSN(V6_vmpy_rt_hf,"Vd32.qf16=vmpy(Vu32.hf,Rt32.hf)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VX_DV,A_HVX_FLT),"Qfloat16
multiply with scalar and hf input",
+{ fHIDE(int i;) fVFOREACH(16, i) { fHIDE(unfloat )u = fPARSEHF(VuV.hf[i]);
fHIDE(unfloat )v = fPARSEHF((RtV >> ((i%2)*16)) & 0xFFFF); fQFMPY(16,VdV,u,v) ;
} })
+
+EXTINSN(V6_vmpy_rt_qf16,"Vd32.qf16=vmpy(Vu32.qf16,Rt32.hf)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VX_DV,A_HVX_FLT),"Qfloat16
multiply with scalar and qf16 input",
+{ fHIDE(int i;) fVFOREACH(16, i) { fHIDE(unfloat )u = fPARSEQF_EXT(16,VuV,i);
fHIDE(unfloat )v = fPARSEHF((RtV >> ((i%2)*16)) & 0xFFFF); fQFMPY(16,VdV,u,v) ;
} })
+
+EXTINSN(V6_vmpy_rt_sf,"Vd32.qf32=vmpy(Vu32.sf,Rt32.sf)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VX_DV,A_HVX_FLT),"Qfloat32
multiply with scalar and sf input",
+{ fHIDE(int i;) fVFOREACH(32, i) { fHIDE(unfloat )u = fPARSESF(VuV.sf[i]);
fHIDE(unfloat )v = fPARSESF(RtV); fQFMPY(32,VdV,u,v) ; } })
+
+EXTINSN(V6_vneg_qf16_hf,"Vd32.qf16=vneg(Vu32.hf)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Negate
and convert hf to qf16",
+{ fHIDE(int i;) fVFOREACH(16, i) { fHIDE(unfloat )u = fPARSEHF(VuV.hf[i]);
u.sign = !u.sign; INIT_UNFLOAT(v) v.exp = E_MIN_EXTQF16; v.sign = 1;
fQFADD(16,VdV,u,v) ; } })
+
+EXTINSN(V6_vneg_qf16_qf16,"Vd32.qf16=vneg(Vu32.qf16)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Negate
and normalize qf16",
+{ fHIDE(int i;) fVFOREACH(16, i) { fHIDE(unfloat )u = fPARSEQF_EXT(16,VuV,i);
u.sign = !u.sign; INIT_UNFLOAT(v) v.exp = E_MIN_EXTQF16; v.sign = 1;
fQFADD(16,VdV,u,v) ; } })
+
+EXTINSN(V6_vneg_qf32_qf32,"Vd32.qf32=vneg(Vu32.qf32)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Negate
and normalize qf32 value",
+{ fHIDE(int i;) fVFOREACH(32, i) { fHIDE(unfloat )u = fPARSEQF_EXT(32,VuV,i);
INIT_UNFLOAT(v) u.sign = !u.sign; v.exp = E_MIN_EXTQF32; v.sign = 1;
fQFADD(32,VdV,u,v) ; } })
+
+EXTINSN(V6_vneg_qf32_sf,"Vd32.qf32=vneg(Vu32.sf)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Negate
and convert sf to qf32",
+{ fHIDE(int i;) fVFOREACH(32, i) { fHIDE(unfloat )u = fPARSESF(VuV.sf[i]);
INIT_UNFLOAT(v) u.sign = !u.sign; v.exp = E_MIN_EXTQF32; v.sign = 1;
fQFADD(32,VdV,u,v) ; } })
+
+EXTINSN(V6_vsub_hf,"Vd32.qf16=vsub(Vu32.hf,Vv32.hf)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Vector
subtraction of hf input",
+{ fHIDE(int i;) fVFOREACH(16, i) { fHIDE(unfloat )u = fPARSEHF(VuV.hf[i]);
fHIDE(unfloat )v = fPARSEHF(VvV.hf[i]); v.sign = !v.sign; fQFADD(16,VdV,u,v) ;
} })
+
+EXTINSN(V6_vsub_hf_mix,"Vd32.qf16=vsub(Vu32.hf,Vv32.qf16)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Vector
subtraction of mixed hf and qf16",
+{ fHIDE(int i;) fVFOREACH(16, i) { fHIDE(unfloat )u = fPARSEHF(VuV.hf[i]);
fHIDE(unfloat )v = fPARSEQF_EXT(16,VvV,i); v.sign = !v.sign; fQFADD(16,VdV,u,v)
; } })
+
+EXTINSN(V6_vsub_qf16,"Vd32.qf16=vsub(Vu32.qf16,Vv32.qf16)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Vector
subtraction of qf16 input",
+{ fHIDE(int i;) fVFOREACH(16, i) { fHIDE(unfloat )u = fPARSEQF_EXT(16,VuV,i);
fHIDE(unfloat )v = fPARSEQF_EXT(16,VvV,i); v.sign = !v.sign; fQFADD(16,VdV,u,v)
; } })
+
+EXTINSN(V6_vsub_qf16_mix,"Vd32.qf16=vsub(Vu32.qf16,Vv32.hf)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Vector
subtraction of mixed qf16 and hf",
+{ fHIDE(int i;) fVFOREACH(16, i) { fHIDE(unfloat )u = fPARSEQF_EXT(16,VuV,i);
fHIDE(unfloat )v = fPARSEHF(VvV.hf[i]); v.sign = !v.sign; fQFADD(16,VdV,u,v) ;
} })
+
+EXTINSN(V6_vsub_qf32,"Vd32.qf32=vsub(Vu32.qf32,Vv32.qf32)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Vector
subtraction of qf32 input",
+{ fHIDE(int i;) fVFOREACH(32, i) { fHIDE(unfloat )u = fPARSEQF_EXT(32,VuV,i);
fHIDE(unfloat )v = fPARSEQF_EXT(32,VvV,i); v.sign = !v.sign; fQFADD(32,VdV,u,v)
; } })
+
+EXTINSN(V6_vsub_qf32_mix,"Vd32.qf32=vsub(Vu32.qf32,Vv32.sf)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Vector
subtraction of mixed qf32 input and sf",
+{ fHIDE(int i;) fVFOREACH(32, i) { fHIDE(unfloat )u = fPARSEQF_EXT(32,VuV,i);
fHIDE(unfloat )v = fPARSESF(VvV.sf[i]); v.sign = !v.sign; fQFADD(32,VdV,u,v) ;
} })
+
+EXTINSN(V6_vsub_sf,"Vd32.qf32=vsub(Vu32.sf,Vv32.sf)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Vector
subtraction of ieee sf input",
+{ fHIDE(int i;) fVFOREACH(32, i) { fHIDE(unfloat )u = fPARSESF(VuV.sf[i]);
fHIDE(unfloat )v = fPARSESF(VvV.sf[i]); v.sign = !v.sign; fQFADD(32,VdV,u,v) ;
} })
+
+EXTINSN(V6_vsub_sf_mix,"Vd32.qf32=vsub(Vu32.sf,Vv32.qf32)",ATTRIBS(A_EXTENSION,A_CVI,A_CVI_VS,A_HVX_FLT),"Vector
subtraction of mixed sf input and qf32",
+{ fHIDE(int i;) fVFOREACH(32, i) { fHIDE(unfloat )u = fPARSESF(VuV.sf[i]);
fHIDE(unfloat )v = fPARSEQF_EXT(32,VvV,i); v.sign = !v.sign; fQFADD(32,VdV,u,v)
; } })
+
/******************************************************************************
DEBUG Vector/Register Printing
******************************************************************************/
--
2.34.1