From nobody Wed Oct 29 20:38:24 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1526085337939656.3385226428951; Fri, 11 May 2018 17:35:37 -0700 (PDT) Received: from localhost ([::1]:58517 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHIVc-0005sx-TY for importer@patchew.org; Fri, 11 May 2018 20:35:36 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59115) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHISZ-00065w-Pa for qemu-devel@nongnu.org; Fri, 11 May 2018 20:32:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fHISY-000887-99 for qemu-devel@nongnu.org; Fri, 11 May 2018 20:32:27 -0400 Received: from mail-pl0-x243.google.com ([2607:f8b0:400e:c01::243]:38667) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fHISY-00087Z-1S for qemu-devel@nongnu.org; Fri, 11 May 2018 20:32:26 -0400 Received: by mail-pl0-x243.google.com with SMTP id c11-v6so4140961plr.5 for ; Fri, 11 May 2018 17:32:25 -0700 (PDT) Received: from cloudburst.twiddle.net (97-113-2-170.tukw.qwest.net. [97.113.2.170]) by smtp.gmail.com with ESMTPSA id v186-v6sm7599735pfb.45.2018.05.11.17.32.23 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 11 May 2018 17:32:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=+NoTAm4TBPlBfRvDj4D7czDRYKfogQkN7zNNR4esdc8=; b=YrCKQAPI59+h75y97yWxRBqFyz/uI3bGjZSEUFJ9u0kvcUlouv30qtcioNaIVzKAO2 6HnAF6v7fLSLqqU2ajQvObGrBqOcMNebNhOUBVJuDgBrxxzUd4rz5Bk+Ts6UY4ugW816 J/3RnWYgn/7yzakotc2VHXW2cbhQX9X3OV++0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=+NoTAm4TBPlBfRvDj4D7czDRYKfogQkN7zNNR4esdc8=; b=ckKZBj7EoRCtDH+rViFpNXLX5GD/svNO7mZvCiIO5sTEPOENf7pQVDkV+il7XC8Aks dlOQYiGPNoho7rMxv7om2vpHjihClTLFj2LGowTfFjrNUMA/gM7oFfA/43HyIXngnzpJ i0KrrvEIJkRb/PCmDW61zFhkE5Zeh9xIbRTFK/1XFNOT52l+9Fm74SzS7NPs4k8yh63v yI3+gv+bpgpnDbBMFK/+EFLFB1WDNVLzJRWV/D6r0VGEMNW7oz6ERzHyHmt/oatjZZo8 4iCWhIwwO0KNFM9hOWCG/8ytdpbYZ6ZEODFxu+NdzO1itFDVQN/MfYCZb2P1zgkB0t75 8rJg== X-Gm-Message-State: ALKqPwdLePkC80Djtk3TXqNZvowDSYpkb3eIL0G53XcjqzHViO6e2TPn 27CxSlhlWyZdE9S4Bn/eu6gjU+n2CIc= X-Google-Smtp-Source: AB8JxZqrjgrLo6jQvAG+ex8nG8olaGFpCrCEth+SozG9Ng0NOO++WyHFqwuwJAOD2/PtGw6fXJRWOw== X-Received: by 2002:a17:902:f44:: with SMTP id 62-v6mr263235ply.318.1526085144723; Fri, 11 May 2018 17:32:24 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Fri, 11 May 2018 17:32:09 -0700 Message-Id: <20180512003217.9105-4-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180512003217.9105-1-richard.henderson@linaro.org> References: <20180512003217.9105-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c01::243 Subject: [Qemu-devel] [PATCH v4 03/11] target/arm: Implement FCVT (scalar, integer) for fp16 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, alex.bennee@linaro.org, qemu-stable@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Cc: qemu-stable@nongnu.org Reviewed-by: Alex Benn=C3=A9e Signed-off-by: Richard Henderson Tested-by: Alex Benn=C3=A9e --- target/arm/helper.h | 6 +++ target/arm/helper.c | 38 ++++++++++++++- target/arm/translate-a64.c | 96 +++++++++++++++++++++++++++++++------- 3 files changed, 122 insertions(+), 18 deletions(-) diff --git a/target/arm/helper.h b/target/arm/helper.h index 1969b37f2d..ce89968b2d 100644 --- a/target/arm/helper.h +++ b/target/arm/helper.h @@ -151,6 +151,10 @@ DEF_HELPER_3(vfp_touhd_round_to_zero, i64, f64, i32, p= tr) DEF_HELPER_3(vfp_tould_round_to_zero, i64, f64, i32, ptr) DEF_HELPER_3(vfp_touhh, i32, f16, i32, ptr) DEF_HELPER_3(vfp_toshh, i32, f16, i32, ptr) +DEF_HELPER_3(vfp_toulh, i32, f16, i32, ptr) +DEF_HELPER_3(vfp_toslh, i32, f16, i32, ptr) +DEF_HELPER_3(vfp_touqh, i64, f16, i32, ptr) +DEF_HELPER_3(vfp_tosqh, i64, f16, i32, ptr) DEF_HELPER_3(vfp_toshs, i32, f32, i32, ptr) DEF_HELPER_3(vfp_tosls, i32, f32, i32, ptr) DEF_HELPER_3(vfp_tosqs, i64, f32, i32, ptr) @@ -177,6 +181,8 @@ DEF_HELPER_3(vfp_ultod, f64, i64, i32, ptr) DEF_HELPER_3(vfp_uqtod, f64, i64, i32, ptr) DEF_HELPER_3(vfp_sltoh, f16, i32, i32, ptr) DEF_HELPER_3(vfp_ultoh, f16, i32, i32, ptr) +DEF_HELPER_3(vfp_sqtoh, f16, i64, i32, ptr) +DEF_HELPER_3(vfp_uqtoh, f16, i64, i32, ptr) =20 DEF_HELPER_FLAGS_2(set_rmode, TCG_CALL_NO_RWG, i32, i32, ptr) DEF_HELPER_FLAGS_2(set_neon_rmode, TCG_CALL_NO_RWG, i32, i32, env) diff --git a/target/arm/helper.c b/target/arm/helper.c index 817f9d81a0..c6fd7f9479 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -11427,8 +11427,12 @@ VFP_CONV_FIX_A64(uq, s, 32, 64, uint64) #undef VFP_CONV_FIX_A64 =20 /* Conversion to/from f16 can overflow to infinity before/after scaling. - * Therefore we convert to f64 (which does not round), scale, - * and then convert f64 to f16 (which may round). + * Therefore we convert to f64, scale, and then convert f64 to f16; or + * vice versa for conversion to integer. + * + * For 16- and 32-bit integers, the conversion to f64 never rounds. + * For 64-bit integers, any integer that would cause rounding will also + * overflow to f16 infinity, so there is no double rounding problem. */ =20 static float16 do_postscale_fp16(float64 f, int shift, float_status *fpst) @@ -11446,6 +11450,16 @@ float16 HELPER(vfp_ultoh)(uint32_t x, uint32_t shi= ft, void *fpst) return do_postscale_fp16(uint32_to_float64(x, fpst), shift, fpst); } =20 +float16 HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst) +{ + return do_postscale_fp16(int64_to_float64(x, fpst), shift, fpst); +} + +float16 HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst) +{ + return do_postscale_fp16(uint64_to_float64(x, fpst), shift, fpst); +} + static float64 do_prescale_fp16(float16 f, int shift, float_status *fpst) { if (unlikely(float16_is_any_nan(f))) { @@ -11475,6 +11489,26 @@ uint32_t HELPER(vfp_touhh)(float16 x, uint32_t shi= ft, void *fpst) return float64_to_uint16(do_prescale_fp16(x, shift, fpst), fpst); } =20 +uint32_t HELPER(vfp_toslh)(float16 x, uint32_t shift, void *fpst) +{ + return float64_to_int32(do_prescale_fp16(x, shift, fpst), fpst); +} + +uint32_t HELPER(vfp_toulh)(float16 x, uint32_t shift, void *fpst) +{ + return float64_to_uint32(do_prescale_fp16(x, shift, fpst), fpst); +} + +uint64_t HELPER(vfp_tosqh)(float16 x, uint32_t shift, void *fpst) +{ + return float64_to_int64(do_prescale_fp16(x, shift, fpst), fpst); +} + +uint64_t HELPER(vfp_touqh)(float16 x, uint32_t shift, void *fpst) +{ + return float64_to_uint64(do_prescale_fp16(x, shift, fpst), fpst); +} + /* Set the current fp rounding mode and return the old one. * The argument is a softfloat float_round_ value. */ diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 11d8c07943..93fb15d185 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -5511,11 +5511,11 @@ static void handle_fpfpcvt(DisasContext *s, int rd,= int rn, int opcode, bool itof, int rmode, int scale, int sf, int ty= pe) { bool is_signed =3D !(opcode & 1); - bool is_double =3D type; TCGv_ptr tcg_fpstatus; - TCGv_i32 tcg_shift; + TCGv_i32 tcg_shift, tcg_single; + TCGv_i64 tcg_double; =20 - tcg_fpstatus =3D get_fpstatus_ptr(false); + tcg_fpstatus =3D get_fpstatus_ptr(type =3D=3D 3); =20 tcg_shift =3D tcg_const_i32(64 - scale); =20 @@ -5533,8 +5533,9 @@ static void handle_fpfpcvt(DisasContext *s, int rd, i= nt rn, int opcode, tcg_int =3D tcg_extend; } =20 - if (is_double) { - TCGv_i64 tcg_double =3D tcg_temp_new_i64(); + switch (type) { + case 1: /* float64 */ + tcg_double =3D tcg_temp_new_i64(); if (is_signed) { gen_helper_vfp_sqtod(tcg_double, tcg_int, tcg_shift, tcg_fpstatus); @@ -5544,8 +5545,10 @@ static void handle_fpfpcvt(DisasContext *s, int rd, = int rn, int opcode, } write_fp_dreg(s, rd, tcg_double); tcg_temp_free_i64(tcg_double); - } else { - TCGv_i32 tcg_single =3D tcg_temp_new_i32(); + break; + + case 0: /* float32 */ + tcg_single =3D tcg_temp_new_i32(); if (is_signed) { gen_helper_vfp_sqtos(tcg_single, tcg_int, tcg_shift, tcg_fpstatus); @@ -5555,6 +5558,23 @@ static void handle_fpfpcvt(DisasContext *s, int rd, = int rn, int opcode, } write_fp_sreg(s, rd, tcg_single); tcg_temp_free_i32(tcg_single); + break; + + case 3: /* float16 */ + tcg_single =3D tcg_temp_new_i32(); + if (is_signed) { + gen_helper_vfp_sqtoh(tcg_single, tcg_int, + tcg_shift, tcg_fpstatus); + } else { + gen_helper_vfp_uqtoh(tcg_single, tcg_int, + tcg_shift, tcg_fpstatus); + } + write_fp_sreg(s, rd, tcg_single); + tcg_temp_free_i32(tcg_single); + break; + + default: + g_assert_not_reached(); } } else { TCGv_i64 tcg_int =3D cpu_reg(s, rd); @@ -5571,8 +5591,9 @@ static void handle_fpfpcvt(DisasContext *s, int rd, i= nt rn, int opcode, =20 gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus); =20 - if (is_double) { - TCGv_i64 tcg_double =3D read_fp_dreg(s, rn); + switch (type) { + case 1: /* float64 */ + tcg_double =3D read_fp_dreg(s, rn); if (is_signed) { if (!sf) { gen_helper_vfp_tosld(tcg_int, tcg_double, @@ -5590,9 +5611,14 @@ static void handle_fpfpcvt(DisasContext *s, int rd, = int rn, int opcode, tcg_shift, tcg_fpstatus); } } + if (!sf) { + tcg_gen_ext32u_i64(tcg_int, tcg_int); + } tcg_temp_free_i64(tcg_double); - } else { - TCGv_i32 tcg_single =3D read_fp_sreg(s, rn); + break; + + case 0: /* float32 */ + tcg_single =3D read_fp_sreg(s, rn); if (sf) { if (is_signed) { gen_helper_vfp_tosqs(tcg_int, tcg_single, @@ -5614,14 +5640,39 @@ static void handle_fpfpcvt(DisasContext *s, int rd,= int rn, int opcode, tcg_temp_free_i32(tcg_dest); } tcg_temp_free_i32(tcg_single); + break; + + case 3: /* float16 */ + tcg_single =3D read_fp_sreg(s, rn); + if (sf) { + if (is_signed) { + gen_helper_vfp_tosqh(tcg_int, tcg_single, + tcg_shift, tcg_fpstatus); + } else { + gen_helper_vfp_touqh(tcg_int, tcg_single, + tcg_shift, tcg_fpstatus); + } + } else { + TCGv_i32 tcg_dest =3D tcg_temp_new_i32(); + if (is_signed) { + gen_helper_vfp_toslh(tcg_dest, tcg_single, + tcg_shift, tcg_fpstatus); + } else { + gen_helper_vfp_toulh(tcg_dest, tcg_single, + tcg_shift, tcg_fpstatus); + } + tcg_gen_extu_i32_i64(tcg_int, tcg_dest); + tcg_temp_free_i32(tcg_dest); + } + tcg_temp_free_i32(tcg_single); + break; + + default: + g_assert_not_reached(); } =20 gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus); tcg_temp_free_i32(tcg_rmode); - - if (!sf) { - tcg_gen_ext32u_i64(tcg_int, tcg_int); - } } =20 tcg_temp_free_ptr(tcg_fpstatus); @@ -5791,7 +5842,20 @@ static void disas_fp_int_conv(DisasContext *s, uint3= 2_t insn) /* actual FP conversions */ bool itof =3D extract32(opcode, 1, 1); =20 - if (type > 1 || (rmode !=3D 0 && opcode > 1)) { + if (rmode !=3D 0 && opcode > 1) { + unallocated_encoding(s); + return; + } + switch (type) { + case 0: /* float32 */ + case 1: /* float64 */ + break; + case 3: /* float16 */ + if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) { + break; + } + /* fallthru */ + default: unallocated_encoding(s); return; } --=20 2.17.0