From nobody Mon Feb 9 20:46:01 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail header.i=@quicinc.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=quicinc.com ARC-Seal: i=1; a=rsa-sha256; t=1617847871; cv=none; d=zohomail.com; s=zohoarc; b=KAHPCsXOGCG/AVoRzuNKO3AEX7qH6JVj/rB7WVzAtqxfrotdyofehycBTtwMPiOgLCvIWRdgZrk4v9dGbyefJ4TJlge3MlobebKOQbvi866SHL9JTFHT9iV+FpD5sF/1KlugtxH1RsQQaupTJuTo38JItEiHLHm0DU577RKBrQ0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1617847871; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=M5/H3WaEWmlld8EGE71PJYusAZ4JbRaLwDqIFLOdjbk=; b=JIrofM9bBda1VmzBnSxD2aQk/Xp5mqLzUpTdANS4wq5iGDIge34HuylF55jcXUa9GdjceBVLfJlN2T4ZH6aU147vdppMfqelxV32wykX7IK2bDt6vfp/sSNc2Ymmmjg8uWYexUuCmU0WBUKUoI4OifAh6pOtYbMDf5Sq9bPi4hg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail header.i=@quicinc.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1617847871413484.69298758519074; Wed, 7 Apr 2021 19:11:11 -0700 (PDT) Received: from localhost ([::1]:59260 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lUK8T-0006bm-GF for importer@patchew.org; Wed, 07 Apr 2021 22:11:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38364) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lUJwa-0000qN-NJ for qemu-devel@nongnu.org; Wed, 07 Apr 2021 21:58:52 -0400 Received: from alexa-out-sd-02.qualcomm.com ([199.106.114.39]:35674) by eggs.gnu.org with esmtps (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1lUJwY-000638-Bd for qemu-devel@nongnu.org; Wed, 07 Apr 2021 21:58:52 -0400 Received: from unknown (HELO ironmsg-SD-alpha.qualcomm.com) ([10.53.140.30]) by alexa-out-sd-02.qualcomm.com with ESMTP; 07 Apr 2021 18:57:57 -0700 Received: from vu-tsimpson-aus.qualcomm.com (HELO vu-tsimpson1-aus.qualcomm.com) ([10.222.150.1]) by ironmsg-SD-alpha.qualcomm.com with ESMTP; 07 Apr 2021 18:57:56 -0700 Received: by vu-tsimpson1-aus.qualcomm.com (Postfix, from userid 47164) id DE7171A6E; Wed, 7 Apr 2021 20:57:54 -0500 (CDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1617847130; x=1649383130; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=69f8YWIy5WdL4Ymu/L1T9JzgLHiclhBDpFlfVM0IGto=; b=WX1acR5fq1tepgwDqbPsEpa0QWPliIg1UoPdIvTwJJq8YVwGJ1ns0NQi o1MeGRrbY7mlTBZM+8TOKYkRa/Cq3wWI4opGwtrYAJjXXXV/SUy+VkAtV /uGehVRNmWydDkFShHM4UA0y+Nm0/0rchcVYwWKY4NRtOrifxawW46nMZ 4=; X-QCInternal: smtphost From: Taylor Simpson To: qemu-devel@nongnu.org Subject: [PATCH v3 18/26] Hexagon (target/hexagon) add F2_sfinvsqrta Date: Wed, 7 Apr 2021 20:57:39 -0500 Message-Id: <1617847067-9867-19-git-send-email-tsimpson@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1617847067-9867-1-git-send-email-tsimpson@quicinc.com> References: <1617847067-9867-1-git-send-email-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=199.106.114.39; envelope-from=tsimpson@qualcomm.com; helo=alexa-out-sd-02.qualcomm.com X-Spam_score_int: -40 X-Spam_score: -4.1 X-Spam_bar: ---- X-Spam_report: (-4.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ale@rev.ng, philmd@redhat.com, tsimpson@quicinc.com, richard.henderson@linaro.org, bcain@quicinc.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Rd32,Pe4 =3D sfinvsqrta(Rs32) Square root approx The helper packs the 2 32-bit results into a 64-bit value, and the fGEN_TCG override unpacks them into the proper results. Test cases in tests/tcg/hexagon/multi_result.c FP exception tests added to tests/tcg/hexagon/fpstuff.c Reviewed-by: Richard Henderson Signed-off-by: Taylor Simpson --- target/hexagon/arch.c | 21 ++++++++++++++++++++- target/hexagon/arch.h | 2 ++ target/hexagon/gen_tcg.h | 16 ++++++++++++++++ target/hexagon/helper.h | 1 + target/hexagon/imported/encode_pp.def | 1 + target/hexagon/imported/float.idef | 16 ++++++++++++++++ target/hexagon/op_helper.c | 21 +++++++++++++++++++++ tests/tcg/hexagon/fpstuff.c | 15 +++++++++++++++ tests/tcg/hexagon/multi_result.c | 29 +++++++++++++++++++++++++++++ 9 files changed, 121 insertions(+), 1 deletion(-) diff --git a/target/hexagon/arch.c b/target/hexagon/arch.c index 46edf45..dee852e 100644 --- a/target/hexagon/arch.c +++ b/target/hexagon/arch.c @@ -247,7 +247,7 @@ int arch_sf_invsqrt_common(float32 *Rs, float32 *Rd, in= t *adjust, int r_exp; int ret =3D 0; RsV =3D *Rs; - if (float32_is_infinity(RsV)) { + if (float32_is_any_nan(RsV)) { if (extract32(RsV, 22, 1) =3D=3D 0) { float_raise(float_flag_invalid, fp_status); } @@ -299,3 +299,22 @@ const uint8_t recip_lookup_table[128] =3D { 0x011, 0x00f, 0x00e, 0x00d, 0x00c, 0x00b, 0x00a, 0x009, 0x008, 0x007, 0x006, 0x005, 0x004, 0x003, 0x002, 0x000, }; + +const uint8_t invsqrt_lookup_table[128] =3D { + 0x069, 0x066, 0x063, 0x061, 0x05e, 0x05b, 0x059, 0x057, + 0x054, 0x052, 0x050, 0x04d, 0x04b, 0x049, 0x047, 0x045, + 0x043, 0x041, 0x03f, 0x03d, 0x03b, 0x039, 0x037, 0x036, + 0x034, 0x032, 0x030, 0x02f, 0x02d, 0x02c, 0x02a, 0x028, + 0x027, 0x025, 0x024, 0x022, 0x021, 0x01f, 0x01e, 0x01d, + 0x01b, 0x01a, 0x019, 0x017, 0x016, 0x015, 0x014, 0x012, + 0x011, 0x010, 0x00f, 0x00d, 0x00c, 0x00b, 0x00a, 0x009, + 0x008, 0x007, 0x006, 0x005, 0x004, 0x003, 0x002, 0x001, + 0x0fe, 0x0fa, 0x0f6, 0x0f3, 0x0ef, 0x0eb, 0x0e8, 0x0e4, + 0x0e1, 0x0de, 0x0db, 0x0d7, 0x0d4, 0x0d1, 0x0ce, 0x0cb, + 0x0c9, 0x0c6, 0x0c3, 0x0c0, 0x0be, 0x0bb, 0x0b8, 0x0b6, + 0x0b3, 0x0b1, 0x0af, 0x0ac, 0x0aa, 0x0a8, 0x0a5, 0x0a3, + 0x0a1, 0x09f, 0x09d, 0x09b, 0x099, 0x097, 0x095, 0x093, + 0x091, 0x08f, 0x08d, 0x08b, 0x089, 0x087, 0x086, 0x084, + 0x082, 0x080, 0x07f, 0x07d, 0x07b, 0x07a, 0x078, 0x077, + 0x075, 0x074, 0x072, 0x071, 0x06f, 0x06e, 0x06c, 0x06b, +}; diff --git a/target/hexagon/arch.h b/target/hexagon/arch.h index b6634e9..3e0c334 100644 --- a/target/hexagon/arch.h +++ b/target/hexagon/arch.h @@ -32,4 +32,6 @@ int arch_sf_invsqrt_common(float32 *Rs, float32 *Rd, int = *adjust, =20 extern const uint8_t recip_lookup_table[128]; =20 +extern const uint8_t invsqrt_lookup_table[128]; + #endif diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h index 428a670..d78e7b8 100644 --- a/target/hexagon/gen_tcg.h +++ b/target/hexagon/gen_tcg.h @@ -216,6 +216,22 @@ tcg_temp_free_i64(tmp); \ } while (0) =20 +/* + * Approximation of the reciprocal square root + * r1,p0 =3D sfinvsqrta(r0) + * + * The helper packs the 2 32-bit results into a 64-bit value, + * so unpack them into the proper results. + */ +#define fGEN_TCG_F2_sfinvsqrta(SHORTCODE) \ + do { \ + TCGv_i64 tmp =3D tcg_temp_new_i64(); \ + gen_helper_sfinvsqrta(tmp, cpu_env, RsV); \ + tcg_gen_extrh_i64_i32(RdV, tmp); \ + tcg_gen_extrl_i64_i32(PeV, tmp); \ + tcg_temp_free_i64(tmp); \ + } while (0) + /* Floating point */ #define fGEN_TCG_F2_conv_sf2df(SHORTCODE) \ gen_helper_conv_sf2df(RddV, cpu_env, RsV) diff --git a/target/hexagon/helper.h b/target/hexagon/helper.h index b377293..cb7508f 100644 --- a/target/hexagon/helper.h +++ b/target/hexagon/helper.h @@ -25,6 +25,7 @@ DEF_HELPER_FLAGS_3(debug_commit_end, TCG_CALL_NO_WG, void= , env, int, int) DEF_HELPER_2(commit_store, void, env, int) DEF_HELPER_FLAGS_4(fcircadd, TCG_CALL_NO_RWG_SE, s32, s32, s32, s32, s32) DEF_HELPER_3(sfrecipa, i64, env, f32, f32) +DEF_HELPER_2(sfinvsqrta, i64, env, f32) =20 /* Floating point */ DEF_HELPER_2(conv_sf2df, f64, env, f32) diff --git a/target/hexagon/imported/encode_pp.def b/target/hexagon/importe= d/encode_pp.def index b01b4d7..18fe45d 100644 --- a/target/hexagon/imported/encode_pp.def +++ b/target/hexagon/imported/encode_pp.def @@ -1642,6 +1642,7 @@ SH2_RR_ENC(F2_conv_sf2w, "1011","100","-","0= 00","ddddd") SH2_RR_ENC(F2_conv_sf2uw_chop, "1011","011","-","001","ddddd") SH2_RR_ENC(F2_conv_sf2w_chop, "1011","100","-","001","ddddd") SH2_RR_ENC(F2_sffixupr, "1011","101","-","000","ddddd") +SH2_RR_ENC(F2_sfinvsqrta, "1011","111","-","0ee","ddddd") =20 =20 DEF_FIELDROW_DESC32(ICLASS_S2op" 1100 -------- PP------ --------","[#= 12] Rd=3D(Rs,#u6)") diff --git a/target/hexagon/imported/float.idef b/target/hexagon/imported/f= loat.idef index eb54158..3e75bc4 100644 --- a/target/hexagon/imported/float.idef +++ b/target/hexagon/imported/float.idef @@ -178,6 +178,22 @@ Q6INSN(F2_sffixupd,"Rd32=3Dsffixupd(Rs32,Rt32)",ATTRIB= S(), RdV =3D RtV; }) =20 +Q6INSN(F2_sfinvsqrta,"Rd32,Pe4=3Dsfinvsqrta(Rs32)",ATTRIBS(), +"Reciprocal Square Root Approximation", +{ + fHIDE(int idx;) + fHIDE(int adjust;) + fHIDE(int mant;) + fHIDE(int exp;) + if (fSF_INVSQRT_COMMON(RsV,RdV,adjust)) { + PeV =3D adjust; + idx =3D (RsV >> 17) & 0x7f; + mant =3D (fSF_INVSQRT_LOOKUP(idx) << 15); + exp =3D fSF_BIAS() - ((fSF_GETEXP(RsV) - fSF_BIAS()) >> 1) - 1; + RdV =3D fMAKESF(fGETBIT(31,RsV),exp,mant); + } +}) + Q6INSN(F2_sffixupr,"Rd32=3Dsffixupr(Rs32)",ATTRIBS(), "Fix Up Radicand", { diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c index 75861e2..a25fb98 100644 --- a/target/hexagon/op_helper.c +++ b/target/hexagon/op_helper.c @@ -326,6 +326,27 @@ uint64_t HELPER(sfrecipa)(CPUHexagonState *env, float3= 2 RsV, float32 RtV) return ((uint64_t)RdV << 32) | PeV; } =20 +uint64_t HELPER(sfinvsqrta)(CPUHexagonState *env, float32 RsV) +{ + int PeV =3D 0; + float32 RdV; + int idx; + int adjust; + int mant; + int exp; + + arch_fpop_start(env); + if (arch_sf_invsqrt_common(&RsV, &RdV, &adjust, &env->fp_status)) { + PeV =3D adjust; + idx =3D (RsV >> 17) & 0x7f; + mant =3D (invsqrt_lookup_table[idx] << 15); + exp =3D SF_BIAS - ((float32_getexp(RsV) - SF_BIAS) >> 1) - 1; + RdV =3D build_float32(extract32(RsV, 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 diff --git a/tests/tcg/hexagon/fpstuff.c b/tests/tcg/hexagon/fpstuff.c index 8e3ba78..0dff429 100644 --- a/tests/tcg/hexagon/fpstuff.c +++ b/tests/tcg/hexagon/fpstuff.c @@ -441,6 +441,20 @@ static void check_canonical_NaN(void) check_fpstatus(usr, 0); } =20 +static void check_invsqrta(void) +{ + int result; + int predval; + + asm volatile("%0,p0 =3D sfinvsqrta(%2)\n\t" + "%1 =3D p0\n\t" + : "+r"(result), "=3Dr"(predval) + : "r"(0x7f800000) + : "p0"); + check32(result, 0xff800000); + check32(predval, 0x0); +} + static void check_float2int_convs() { int res32; @@ -590,6 +604,7 @@ int main() check_dfminmax(); check_recip_exception(); check_canonical_NaN(); + check_invsqrta(); check_float2int_convs(); =20 puts(err ? "FAIL" : "PASS"); diff --git a/tests/tcg/hexagon/multi_result.c b/tests/tcg/hexagon/multi_res= ult.c index cb7dd31..67aa462 100644 --- a/tests/tcg/hexagon/multi_result.c +++ b/tests/tcg/hexagon/multi_result.c @@ -31,6 +31,20 @@ static int sfrecipa(int Rs, int Rt, int *pred_result) return result; } =20 +static int sfinvsqrta(int Rs, int *pred_result) +{ + int result; + int predval; + + asm volatile("%0,p0 =3D sfinvsqrta(%2)\n\t" + "%1 =3D p0\n\t" + : "+r"(result), "=3Dr"(predval) + : "r"(Rs) + : "p0"); + *pred_result =3D predval; + return result; +} + int err; =20 static void check(int val, int expect) @@ -59,9 +73,24 @@ static void test_sfrecipa() check_p(pred_result, 0x00); } =20 +static void test_sfinvsqrta() +{ + int res; + int pred_result; + + res =3D sfinvsqrta(0x04030201, &pred_result); + check(res, 0x4d330000); + check_p(pred_result, 0xe0); + + res =3D sfinvsqrta(0x0, &pred_result); + check(res, 0x3f800000); + check_p(pred_result, 0x0); +} + int main() { test_sfrecipa(); + test_sfinvsqrta(); =20 puts(err ? "FAIL" : "PASS"); return err; --=20 2.7.4