From patchwork Mon Jul 23 20:17:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Michael Roth X-Patchwork-Id: 142659 Delivered-To: patch@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp6515840ljj; Mon, 23 Jul 2018 14:30:34 -0700 (PDT) X-Google-Smtp-Source: AAOMgpd4j1YXIjvCJ9ECmK2h6fzqVqHkk1BNZVWjuDtAJggCQLx3mii9Lkh+O2+ES1mByw/YQX8F X-Received: by 2002:a37:d401:: with SMTP id l1-v6mr12675029qki.221.1532381434518; Mon, 23 Jul 2018 14:30:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1532381434; cv=none; d=google.com; s=arc-20160816; b=rMO+HEHZVcEhwPMzJ9ibLviRSwEPo/zlWMknW4/Rsq5pd7RGYvtflU3HYjUCQBvJLW iZLRoJ59XzgncorafF7FrVXlTbMRqcLeW+ANPGOk1HElsmHAl04R1Z99jUOeIchxCbl5 umi2SuG/QkShR2CgySB7nzeI60JxZwajU+mkYaXynFKLDwDWTOpiOK63iHlOZpsxHTrI 0Xt691AJEzwVsQ9LJ+fTv3tBmENXfj84OLU+iHEhoQZg5TDYfgSi2P6S1v3tr0geLQXq X23/1n8AohQwsq9ILxOyE1383fsMpelhdMBIsRvWRHfT0wje+WXsCLSn4VHT4g7j3/4p 7p1g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=FdarBSs+mctGDElKHbhV5ZEMxApRQE8DJ91JheNMCxs=; b=y9P/8EEJ4qieIg7NoATtNsiUg29ITHJdRoXheD1CStZ59Neily+scA5eOiIA+ZxmTn C3nFS39eDfKkSpGz6d5RLsmwdnDiWxUNuP9JKWzngNCEQYiQW9ziZIhO8i+m03YJpkrV R4I8I8x1bDu8zz/jkYVuJJ06kIdhE03xWJmKF6C72PMnG6/UKpIUW9BI/onyBvxcjRX4 ejcDcC6I6qkr3GFQe+0CK63pvFqAWCaf0a4dJtbcdGoBoBT7s4JrWQGXnexTGYW7WCQk UMbE+mSJArmk1eIk54nAl6KmT61ngU9yUUh3gKczyyrRUkOrOFUFjFUgNEYqs1JCi+yc FM4Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=jeRJCdyv; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ibm.com Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id o37-v6si1265077qvh.216.2018.07.23.14.30.34 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 23 Jul 2018 14:30:34 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=jeRJCdyv; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ibm.com Received: from localhost ([::1]:36791 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fhiPZ-0007Gy-QN for patch@linaro.org; Mon, 23 Jul 2018 17:30:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43091) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fhhKf-0003rc-H6 for qemu-devel@nongnu.org; Mon, 23 Jul 2018 16:21:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fhhKd-0005LW-Tk for qemu-devel@nongnu.org; Mon, 23 Jul 2018 16:21:25 -0400 Received: from mail-oi0-x241.google.com ([2607:f8b0:4003:c06::241]:42738) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fhhKd-0005L1-L4; Mon, 23 Jul 2018 16:21:23 -0400 Received: by mail-oi0-x241.google.com with SMTP id n84-v6so3472600oib.9; Mon, 23 Jul 2018 13:21:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=FdarBSs+mctGDElKHbhV5ZEMxApRQE8DJ91JheNMCxs=; b=jeRJCdyv5wsTuKpnPvL16A99L13SgRYF7I4hg5E4T2AFIPvM6eXM9+mUNAf/U7Sc+t oYYfaOe5d8yYC6sZ+0Z7Hz0K3lDqjxCfnOdGjPTBhpG4CxYbA3xpEDHL/1QoIKoHR6nR 1XgAvfJ3YmS3wCKa7HvSKK/RPFuwjZSzDADAA6HgaEY2ub/I9PVWZrUflui4548TpJXG hK6Sx/rLUtW7xWKIcrus4y5V/nAH1T6YgFD+UN6PAuuIvKEFqRgj0nXJmFEiZQvDEqKf /2UQtmaaowBlreflrfZ3xxdejZDjotkfVy5vtsvLgagdwiiSioeVpPOVsfn+bQdKq96c wl1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=FdarBSs+mctGDElKHbhV5ZEMxApRQE8DJ91JheNMCxs=; b=iok7FnzVtlHE/t/JHHz+Y0R7SHM8TRIGB+1fPkW9p0HB7QA5GPdfGHTyo6AbLVHnXo ml0mc3AmqaVgCFTc9PD+/lvKFQCZO+TWEGyBXOZx3aynkVmfxN53Yzh9MirC1JHtnv46 4McDNfpabDq7J5m6yIuYoy1ImSPLWPoDzCYk9whpBuSSjsaNkbnP4QMhoxJjJhv1RF7s CkIBRfQVPInMGplzCFQ4DaLSjdADvR6Ye7q7z7xYsEPkF117O3siHZHbAMtP+jocOQUA 2uCve/oVWigz2eU80u4I1JBJl7miH8XjCE5/JFW10rGvTxuLB70h0J2fdNBlZowZYVDJ dXCQ== X-Gm-Message-State: AOUpUlHzdQthORwKdgxmBAEt55dGZSPhLyHpjw8/aR+wfsX1Q+jn5+B9 Bjrapnvk9XiMhrCCRxsEMzHhbOz80MRgng== X-Received: by 2002:aca:dc08:: with SMTP id t8-v6mr340065oig.226.1532377282407; Mon, 23 Jul 2018 13:21:22 -0700 (PDT) Received: from localhost (76-251-165-188.lightspeed.austtx.sbcglobal.net. [76.251.165.188]) by smtp.gmail.com with ESMTPSA id e125-v6sm9839232oig.4.2018.07.23.13.21.20 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 23 Jul 2018 13:21:21 -0700 (PDT) From: Michael Roth To: qemu-devel@nongnu.org Date: Mon, 23 Jul 2018 15:17:26 -0500 Message-Id: <20180723201748.25573-78-mdroth@linux.vnet.ibm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com> References: <20180723201748.25573-1-mdroth@linux.vnet.ibm.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4003:c06::241 Subject: [Qemu-devel] [PATCH 77/99] 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 , Richard Henderson , qemu-stable@nongnu.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Cc: qemu-stable@nongnu.org Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson Tested-by: Alex Bennée Message-id: 20180512003217.9105-4-richard.henderson@linaro.org Signed-off-by: Peter Maydell (cherry picked from commit 564a0632504fad840491aa9a59453f4e64a316c4) Signed-off-by: Michael Roth --- target/arm/helper.c | 38 ++++++++++++++- target/arm/helper.h | 6 +++ target/arm/translate-a64.c | 96 +++++++++++++++++++++++++++++++------- 3 files changed, 122 insertions(+), 18 deletions(-) -- 2.17.1 diff --git a/target/arm/helper.c b/target/arm/helper.c index c07c1d7f48..1043d6ed32 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -11416,8 +11416,12 @@ VFP_CONV_FIX_A64(uq, s, 32, 64, uint64) #undef VFP_CONV_FIX_A64 /* 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. */ static float16 do_postscale_fp16(float64 f, int shift, float_status *fpst) @@ -11435,6 +11439,16 @@ float16 HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst) return do_postscale_fp16(uint32_to_float64(x, fpst), shift, fpst); } +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))) { @@ -11464,6 +11478,26 @@ uint32_t HELPER(vfp_touhh)(float16 x, uint32_t shift, void *fpst) return float64_to_uint16(do_prescale_fp16(x, shift, fpst), fpst); } +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/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, ptr) 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) 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/translate-a64.c b/target/arm/translate-a64.c index b05f9bfe91..33be611bdb 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -5268,11 +5268,11 @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode, bool itof, int rmode, int scale, int sf, int type) { bool is_signed = !(opcode & 1); - bool is_double = type; TCGv_ptr tcg_fpstatus; - TCGv_i32 tcg_shift; + TCGv_i32 tcg_shift, tcg_single; + TCGv_i64 tcg_double; - tcg_fpstatus = get_fpstatus_ptr(false); + tcg_fpstatus = get_fpstatus_ptr(type == 3); tcg_shift = tcg_const_i32(64 - scale); @@ -5290,8 +5290,9 @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode, tcg_int = tcg_extend; } - if (is_double) { - TCGv_i64 tcg_double = tcg_temp_new_i64(); + switch (type) { + case 1: /* float64 */ + tcg_double = tcg_temp_new_i64(); if (is_signed) { gen_helper_vfp_sqtod(tcg_double, tcg_int, tcg_shift, tcg_fpstatus); @@ -5301,8 +5302,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 = tcg_temp_new_i32(); + break; + + case 0: /* float32 */ + tcg_single = tcg_temp_new_i32(); if (is_signed) { gen_helper_vfp_sqtos(tcg_single, tcg_int, tcg_shift, tcg_fpstatus); @@ -5312,6 +5315,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 = 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 = cpu_reg(s, rd); @@ -5328,8 +5348,9 @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode, gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus); - if (is_double) { - TCGv_i64 tcg_double = read_fp_dreg(s, rn); + switch (type) { + case 1: /* float64 */ + tcg_double = read_fp_dreg(s, rn); if (is_signed) { if (!sf) { gen_helper_vfp_tosld(tcg_int, tcg_double, @@ -5347,9 +5368,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 = read_fp_sreg(s, rn); + break; + + case 0: /* float32 */ + tcg_single = read_fp_sreg(s, rn); if (sf) { if (is_signed) { gen_helper_vfp_tosqs(tcg_int, tcg_single, @@ -5371,14 +5397,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 = 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 = 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(); } 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); - } } tcg_temp_free_ptr(tcg_fpstatus); @@ -5548,7 +5599,20 @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn) /* actual FP conversions */ bool itof = extract32(opcode, 1, 1); - if (type > 1 || (rmode != 0 && opcode > 1)) { + if (rmode != 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; }