aboutsummaryrefslogtreecommitdiff
path: root/target/hexagon/op_helper.c
diff options
context:
space:
mode:
authorTaylor Simpson <tsimpson@quicinc.com>2021-04-08 20:07:45 -0500
committerRichard Henderson <richard.henderson@linaro.org>2021-05-01 08:31:43 -0700
commitd934c16d8a1e0fb82fd4abfa54dcb5217430577c (patch)
tree4f98424f1036f09e712d80be7ba95faf130c17ab /target/hexagon/op_helper.c
parent85580a65577898288a29d849160601895979c661 (diff)
downloadqemu-d934c16d8a1e0fb82fd4abfa54dcb5217430577c.zip
qemu-d934c16d8a1e0fb82fd4abfa54dcb5217430577c.tar.gz
qemu-d934c16d8a1e0fb82fd4abfa54dcb5217430577c.tar.bz2
Hexagon (target/hexagon) add F2_sfrecipa instruction
Rd32,Pe4 = sfrecipa(Rs32, Rt32) Recripocal approx Test cases in tests/tcg/hexagon/multi_result.c FP exception tests added to tests/tcg/hexagon/fpstuff.c Signed-off-by: Taylor Simpson <tsimpson@quicinc.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <1617930474-31979-18-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/hexagon/op_helper.c')
-rw-r--r--target/hexagon/op_helper.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 33b6713..75861e2 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -289,6 +289,43 @@ int32_t HELPER(fcircadd)(int32_t RxV, int32_t offset, int32_t M, int32_t CS)
return new_ptr;
}
+static float32 build_float32(uint8_t sign, uint32_t exp, uint32_t mant)
+{
+ return make_float32(
+ ((sign & 1) << 31) |
+ ((exp & 0xff) << SF_MANTBITS) |
+ (mant & ((1 << SF_MANTBITS) - 1)));
+}
+
+/*
+ * sfrecipa, sfinvsqrta have two 32-bit results
+ * r0,p0=sfrecipa(r1,r2)
+ * r0,p0=sfinvsqrta(r1)
+ *
+ * Since helpers can only return a single value, we pack the two results
+ * into a 64-bit value.
+ */
+uint64_t HELPER(sfrecipa)(CPUHexagonState *env, float32 RsV, float32 RtV)
+{
+ int32_t PeV = 0;
+ float32 RdV;
+ int idx;
+ int adjust;
+ int mant;
+ int exp;
+
+ arch_fpop_start(env);
+ if (arch_sf_recip_common(&RsV, &RtV, &RdV, &adjust, &env->fp_status)) {
+ PeV = adjust;
+ idx = (RtV >> 16) & 0x7f;
+ mant = (recip_lookup_table[idx] << 15) | 1;
+ exp = SF_BIAS - (float32_getexp(RtV) - SF_BIAS) - 1;
+ RdV = build_float32(extract32(RtV, 31, 1), exp, mant);
+ }
+ arch_fpop_end(env);
+ return ((uint64_t)RdV << 32) | PeV;
+}
+
/*
* mem_noshuf
* Section 5.5 of the Hexagon V67 Programmer's Reference Manual