From patchwork Thu Feb 20 11:17:13 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 25008 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qc0-f199.google.com (mail-qc0-f199.google.com [209.85.216.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 48EC1203BE for ; Thu, 20 Feb 2014 11:18:41 +0000 (UTC) Received: by mail-qc0-f199.google.com with SMTP id m20sf3340567qcx.2 for ; Thu, 20 Feb 2014 03:18:41 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:date :message-id:in-reply-to:references:cc:subject:precedence:list-id :list-unsubscribe:list-archive:list-post:list-help:list-subscribe :errors-to:sender:x-original-sender :x-original-authentication-results:mailing-list; bh=SXLTRx0oCQ6h9Jhp9rbR8+XfmmM8nwVrB7N21sX0rWc=; b=HHcS5ceoi1Mrcobl9+u/tSc93lEqYHhzn0L+twstYdZsowc15HxyvHdzsE7syO6+e3 xR9CmndRVe6pLmSbVogBT3b/hmn56FA/txjhcW+ukpSiprdJ3oIkaDnC3vDZgrawqC2t JB33DwQQe3WLXKxd1dDeky44CaO5QeswQOKTCtaVvbCzRrr9YBYRUgQBf5ch107x1/aW QSSlZapmFzMuL/hywc1md2k6kDa2OWPuoPIlB7x10MBJkJAn0DhxNt9ybK+Kc+CiTUOo aOEFomZvNPNTJN3OiRD09kiQcaXCCU7mvd+pmPbLVZZbToKtHzqPNQKRZp3AUBS4sccQ 6RcQ== X-Gm-Message-State: ALoCoQkVydpNCVNKyG0snxHdQimfFZ9ONpXCYvfDC3MTn5B9AgSpBC/5aupDBmiGcP5SHYNd8Zo1 X-Received: by 10.236.190.199 with SMTP id e47mr367879yhn.53.1392895121058; Thu, 20 Feb 2014 03:18:41 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.47.227 with SMTP id m90ls511649qga.38.gmail; Thu, 20 Feb 2014 03:18:40 -0800 (PST) X-Received: by 10.220.252.71 with SMTP id mv7mr666783vcb.68.1392895120923; Thu, 20 Feb 2014 03:18:40 -0800 (PST) Received: from mail-ve0-f182.google.com (mail-ve0-f182.google.com [209.85.128.182]) by mx.google.com with ESMTPS id 8si28155vct.119.2014.02.20.03.18.40 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 20 Feb 2014 03:18:40 -0800 (PST) Received-SPF: neutral (google.com: 209.85.128.182 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.128.182; Received: by mail-ve0-f182.google.com with SMTP id jy13so1719944veb.13 for ; Thu, 20 Feb 2014 03:18:40 -0800 (PST) X-Received: by 10.220.98.204 with SMTP id r12mr700140vcn.48.1392895120850; Thu, 20 Feb 2014 03:18:40 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.174.196 with SMTP id u4csp50072vcz; Thu, 20 Feb 2014 03:18:40 -0800 (PST) X-Received: by 10.224.127.7 with SMTP id e7mr742542qas.5.1392895119707; Thu, 20 Feb 2014 03:18:39 -0800 (PST) Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id q16si1657840qga.81.2014.02.20.03.18.39 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 20 Feb 2014 03:18:39 -0800 (PST) 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; Received: from localhost ([::1]:37530 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WGReJ-0002eV-5X for patch@linaro.org; Thu, 20 Feb 2014 06:18:39 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58481) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WGRdQ-0001yT-L2 for qemu-devel@nongnu.org; Thu, 20 Feb 2014 06:17:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WGRdO-0004jB-SC for qemu-devel@nongnu.org; Thu, 20 Feb 2014 06:17:44 -0500 Received: from mnementh.archaic.org.uk ([2001:8b0:1d0::1]:46019) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WGRdO-0004gz-H1 for qemu-devel@nongnu.org; Thu, 20 Feb 2014 06:17:42 -0500 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1WGRdG-0003SS-Un; Thu, 20 Feb 2014 11:17:34 +0000 From: Peter Maydell To: Anthony Liguori Date: Thu, 20 Feb 2014 11:17:13 +0000 Message-Id: <1392895054-13232-10-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1392895054-13232-1-git-send-email-peter.maydell@linaro.org> References: <1392895054-13232-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:8b0:1d0::1 Cc: Blue Swirl , qemu-devel@nongnu.org, Aurelien Jarno Subject: [Qemu-devel] [PULL 09/30] target-arm: A64: Implement remaining 3-same instructions X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: peter.maydell@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.128.182 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 Implement the remaining instructions in the SIMD 3-reg-same and scalar-3-reg-same groups: FMULX, FRECPS, FRSQRTS, FACGE, FACGT, FMLA and FMLS. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- target-arm/helper-a64.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++ target-arm/helper-a64.h | 4 ++++ target-arm/helper.h | 2 ++ target-arm/neon_helper.c | 16 +++++++++++++ target-arm/translate-a64.c | 52 ++++++++++++++++++++++++++++++++++++---- 5 files changed, 130 insertions(+), 4 deletions(-) diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c index b4cab51..c2ce33e 100644 --- a/target-arm/helper-a64.c +++ b/target-arm/helper-a64.c @@ -198,3 +198,63 @@ uint64_t HELPER(neon_cgt_f64)(float64 a, float64 b, void *fpstp) float_status *fpst = fpstp; return -float64_lt(b, a, fpst); } + +/* Reciprocal step and sqrt step. Note that unlike the A32/T32 + * versions, these do a fully fused multiply-add or + * multiply-add-and-halve. + */ +#define float32_two make_float32(0x40000000) +#define float32_three make_float32(0x40400000) +#define float32_one_point_five make_float32(0x3fc00000) + +#define float64_two make_float64(0x4000000000000000ULL) +#define float64_three make_float64(0x4008000000000000ULL) +#define float64_one_point_five make_float64(0x3FF8000000000000ULL) + +float32 HELPER(recpsf_f32)(float32 a, float32 b, void *fpstp) +{ + float_status *fpst = fpstp; + + a = float32_chs(a); + if ((float32_is_infinity(a) && float32_is_zero(b)) || + (float32_is_infinity(b) && float32_is_zero(a))) { + return float32_two; + } + return float32_muladd(a, b, float32_two, 0, fpst); +} + +float64 HELPER(recpsf_f64)(float64 a, float64 b, void *fpstp) +{ + float_status *fpst = fpstp; + + a = float64_chs(a); + if ((float64_is_infinity(a) && float64_is_zero(b)) || + (float64_is_infinity(b) && float64_is_zero(a))) { + return float64_two; + } + return float64_muladd(a, b, float64_two, 0, fpst); +} + +float32 HELPER(rsqrtsf_f32)(float32 a, float32 b, void *fpstp) +{ + float_status *fpst = fpstp; + + a = float32_chs(a); + if ((float32_is_infinity(a) && float32_is_zero(b)) || + (float32_is_infinity(b) && float32_is_zero(a))) { + return float32_one_point_five; + } + return float32_muladd(a, b, float32_three, float_muladd_halve_result, fpst); +} + +float64 HELPER(rsqrtsf_f64)(float64 a, float64 b, void *fpstp) +{ + float_status *fpst = fpstp; + + a = float64_chs(a); + if ((float64_is_infinity(a) && float64_is_zero(b)) || + (float64_is_infinity(b) && float64_is_zero(a))) { + return float64_one_point_five; + } + return float64_muladd(a, b, float64_three, float_muladd_halve_result, fpst); +} diff --git a/target-arm/helper-a64.h b/target-arm/helper-a64.h index bf20466..ab9933c 100644 --- a/target-arm/helper-a64.h +++ b/target-arm/helper-a64.h @@ -32,3 +32,7 @@ DEF_HELPER_FLAGS_3(vfp_mulxd, TCG_CALL_NO_RWG, f64, f64, f64, ptr) DEF_HELPER_FLAGS_3(neon_ceq_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr) DEF_HELPER_FLAGS_3(neon_cge_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr) DEF_HELPER_FLAGS_3(neon_cgt_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr) +DEF_HELPER_FLAGS_3(recpsf_f32, TCG_CALL_NO_RWG, f32, f32, f32, ptr) +DEF_HELPER_FLAGS_3(recpsf_f64, TCG_CALL_NO_RWG, f64, f64, f64, ptr) +DEF_HELPER_FLAGS_3(rsqrtsf_f32, TCG_CALL_NO_RWG, f32, f32, f32, ptr) +DEF_HELPER_FLAGS_3(rsqrtsf_f64, TCG_CALL_NO_RWG, f64, f64, f64, ptr) diff --git a/target-arm/helper.h b/target-arm/helper.h index 951e6ad..7c60121 100644 --- a/target-arm/helper.h +++ b/target-arm/helper.h @@ -382,6 +382,8 @@ DEF_HELPER_3(neon_cge_f32, i32, i32, i32, ptr) DEF_HELPER_3(neon_cgt_f32, i32, i32, i32, ptr) DEF_HELPER_3(neon_acge_f32, i32, i32, i32, ptr) DEF_HELPER_3(neon_acgt_f32, i32, i32, i32, ptr) +DEF_HELPER_3(neon_acge_f64, i64, i64, i64, ptr) +DEF_HELPER_3(neon_acgt_f64, i64, i64, i64, ptr) /* iwmmxt_helper.c */ DEF_HELPER_2(iwmmxt_maddsq, i64, i64, i64) diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c index b4c8690..13752ba 100644 --- a/target-arm/neon_helper.c +++ b/target-arm/neon_helper.c @@ -1823,6 +1823,22 @@ uint32_t HELPER(neon_acgt_f32)(uint32_t a, uint32_t b, void *fpstp) return -float32_lt(f1, f0, fpst); } +uint64_t HELPER(neon_acge_f64)(uint64_t a, uint64_t b, void *fpstp) +{ + float_status *fpst = fpstp; + float64 f0 = float64_abs(make_float64(a)); + float64 f1 = float64_abs(make_float64(b)); + return -float64_le(f1, f0, fpst); +} + +uint64_t HELPER(neon_acgt_f64)(uint64_t a, uint64_t b, void *fpstp) +{ + float_status *fpst = fpstp; + float64 f0 = float64_abs(make_float64(a)); + float64 f1 = float64_abs(make_float64(b)); + return -float64_lt(f1, f0, fpst); +} + #define ELEM(V, N, SIZE) (((V) >> ((N) * (SIZE))) & ((1ull << (SIZE)) - 1)) void HELPER(neon_qunzip8)(CPUARMState *env, uint32_t rd, uint32_t rm) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 91128f5..c96ba68 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -6045,18 +6045,33 @@ static void handle_3same_float(DisasContext *s, int size, int elements, read_vec_element(s, tcg_op2, rm, pass, MO_64); switch (fpopcode) { + case 0x39: /* FMLS */ + /* As usual for ARM, separate negation for fused multiply-add */ + gen_helper_vfp_negd(tcg_op1, tcg_op1); + /* fall through */ + case 0x19: /* FMLA */ + read_vec_element(s, tcg_res, rd, pass, MO_64); + gen_helper_vfp_muladdd(tcg_res, tcg_op1, tcg_op2, + tcg_res, fpst); + break; case 0x18: /* FMAXNM */ gen_helper_vfp_maxnumd(tcg_res, tcg_op1, tcg_op2, fpst); break; case 0x1a: /* FADD */ gen_helper_vfp_addd(tcg_res, tcg_op1, tcg_op2, fpst); break; + case 0x1b: /* FMULX */ + gen_helper_vfp_mulxd(tcg_res, tcg_op1, tcg_op2, fpst); + break; case 0x1c: /* FCMEQ */ gen_helper_neon_ceq_f64(tcg_res, tcg_op1, tcg_op2, fpst); break; case 0x1e: /* FMAX */ gen_helper_vfp_maxd(tcg_res, tcg_op1, tcg_op2, fpst); break; + case 0x1f: /* FRECPS */ + gen_helper_recpsf_f64(tcg_res, tcg_op1, tcg_op2, fpst); + break; case 0x38: /* FMINNM */ gen_helper_vfp_minnumd(tcg_res, tcg_op1, tcg_op2, fpst); break; @@ -6066,12 +6081,18 @@ static void handle_3same_float(DisasContext *s, int size, int elements, case 0x3e: /* FMIN */ gen_helper_vfp_mind(tcg_res, tcg_op1, tcg_op2, fpst); break; + case 0x3f: /* FRSQRTS */ + gen_helper_rsqrtsf_f64(tcg_res, tcg_op1, tcg_op2, fpst); + break; case 0x5b: /* FMUL */ gen_helper_vfp_muld(tcg_res, tcg_op1, tcg_op2, fpst); break; case 0x5c: /* FCMGE */ gen_helper_neon_cge_f64(tcg_res, tcg_op1, tcg_op2, fpst); break; + case 0x5d: /* FACGE */ + gen_helper_neon_acge_f64(tcg_res, tcg_op1, tcg_op2, fpst); + break; case 0x5f: /* FDIV */ gen_helper_vfp_divd(tcg_res, tcg_op1, tcg_op2, fpst); break; @@ -6082,6 +6103,9 @@ static void handle_3same_float(DisasContext *s, int size, int elements, case 0x7c: /* FCMGT */ gen_helper_neon_cgt_f64(tcg_res, tcg_op1, tcg_op2, fpst); break; + case 0x7d: /* FACGT */ + gen_helper_neon_acgt_f64(tcg_res, tcg_op1, tcg_op2, fpst); + break; default: g_assert_not_reached(); } @@ -6101,15 +6125,30 @@ static void handle_3same_float(DisasContext *s, int size, int elements, read_vec_element_i32(s, tcg_op2, rm, pass, MO_32); switch (fpopcode) { + case 0x39: /* FMLS */ + /* As usual for ARM, separate negation for fused multiply-add */ + gen_helper_vfp_negs(tcg_op1, tcg_op1); + /* fall through */ + case 0x19: /* FMLA */ + read_vec_element_i32(s, tcg_res, rd, pass, MO_32); + gen_helper_vfp_muladds(tcg_res, tcg_op1, tcg_op2, + tcg_res, fpst); + break; case 0x1a: /* FADD */ gen_helper_vfp_adds(tcg_res, tcg_op1, tcg_op2, fpst); break; + case 0x1b: /* FMULX */ + gen_helper_vfp_mulxs(tcg_res, tcg_op1, tcg_op2, fpst); + break; case 0x1c: /* FCMEQ */ gen_helper_neon_ceq_f32(tcg_res, tcg_op1, tcg_op2, fpst); break; case 0x1e: /* FMAX */ gen_helper_vfp_maxs(tcg_res, tcg_op1, tcg_op2, fpst); break; + case 0x1f: /* FRECPS */ + gen_helper_recpsf_f32(tcg_res, tcg_op1, tcg_op2, fpst); + break; case 0x18: /* FMAXNM */ gen_helper_vfp_maxnums(tcg_res, tcg_op1, tcg_op2, fpst); break; @@ -6122,12 +6161,18 @@ static void handle_3same_float(DisasContext *s, int size, int elements, case 0x3e: /* FMIN */ gen_helper_vfp_mins(tcg_res, tcg_op1, tcg_op2, fpst); break; + case 0x3f: /* FRSQRTS */ + gen_helper_rsqrtsf_f32(tcg_res, tcg_op1, tcg_op2, fpst); + break; case 0x5b: /* FMUL */ gen_helper_vfp_muls(tcg_res, tcg_op1, tcg_op2, fpst); break; case 0x5c: /* FCMGE */ gen_helper_neon_cge_f32(tcg_res, tcg_op1, tcg_op2, fpst); break; + case 0x5d: /* FACGE */ + gen_helper_neon_acge_f32(tcg_res, tcg_op1, tcg_op2, fpst); + break; case 0x5f: /* FDIV */ gen_helper_vfp_divs(tcg_res, tcg_op1, tcg_op2, fpst); break; @@ -6138,6 +6183,9 @@ static void handle_3same_float(DisasContext *s, int size, int elements, case 0x7c: /* FCMGT */ gen_helper_neon_cgt_f32(tcg_res, tcg_op1, tcg_op2, fpst); break; + case 0x7d: /* FACGT */ + gen_helper_neon_acgt_f32(tcg_res, tcg_op1, tcg_op2, fpst); + break; default: g_assert_not_reached(); } @@ -6192,8 +6240,6 @@ static void disas_simd_scalar_three_reg_same(DisasContext *s, uint32_t insn) case 0x3f: /* FRSQRTS */ case 0x5d: /* FACGE */ case 0x7d: /* FACGT */ - unsupported_encoding(s, insn); - return; case 0x1c: /* FCMEQ */ case 0x5c: /* FCMGE */ case 0x7c: /* FCMGT */ @@ -7303,8 +7349,6 @@ static void disas_simd_3same_float(DisasContext *s, uint32_t insn) case 0x7d: /* FACGT */ case 0x19: /* FMLA */ case 0x39: /* FMLS */ - unsupported_encoding(s, insn); - return; case 0x18: /* FMAXNM */ case 0x1a: /* FADD */ case 0x1c: /* FCMEQ */