From patchwork Mon Jun 21 16:28:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 464573 Delivered-To: patch@linaro.org Received: by 2002:a17:906:71d0:0:0:0:0 with SMTP id i16csp4383896ejk; Mon, 21 Jun 2021 09:55:38 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxU8YuMYigSalYHaAutRTNJmoajlB3Q1JQH2tH6jUSPAbP6+ZLCB31VymkMupjdltjclmGG X-Received: by 2002:a67:bb14:: with SMTP id m20mr18856441vsn.0.1624294538309; Mon, 21 Jun 2021 09:55:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1624294538; cv=none; d=google.com; s=arc-20160816; b=Zavia46/csvXDBTT7iS1h69nUbwOZmngTCKuJSo935a0hmps5bXt+X5B+U7fuePPSi Q/fcTSMqrY7JN3T1im3EY96KDBZA+Zp4aLuLW5/5Gpb5+ChBioNnlEPnnEP+5PGnA7CV Rp/PPyavusC1vgg4jDpsFQ9KN48TWsUkKHOPVtedtuUhgDCCZooXGS7PhkbI1tLsqCOV HczFyGEp025XcfxLBaUluAm5wZZ+DMX0or+Y9toZpkKbE7j8zuLYCSeqcMe4ZLgK+7E5 9riBrRx2B8XXaoi2YRkTNMjZmadWsDJUusQ+9Us8Ttp61tdBvTjskQfRrmC/eN36TB8m 8X/Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=/JCC4OyoVW6+mhRPcZdtNM8Y0F4eJiGOfrPF39mhaX8=; b=llmtls7yiutw75sFPr3twQ8J/i/mnGuDDR/Uj1FpQMWuQAqgrshPZDtrhQO/kJuzeq c/QKgi2/CFitpuUQOWR0DBJCqymDbTYaGfRrUkHpwHyejGrexCnnIPXCUlmFwjFYOeQx Aee75aW2JSUnPatIEauqAoF0eJXIYR71nihvkTnc6+0BNupW6jenyyoWJ4hKo3t4Q/By uaBgrXDMYhLwOPxDWnnK/PwWI6c1Xw+6b7u0QJEbsesEdsK9nDs1MesmTO8mTU/6qdA0 YJfcnYlML/dJVsT6H43g8IS/cjZ2DN3DttZVRzDJ11C4LozsrXf47SnRjuWomCet1pUL 89XA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=dvEb4+6A; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id 16si15324906vkf.68.2021.06.21.09.55.38 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Mon, 21 Jun 2021 09:55:38 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=dvEb4+6A; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:55976 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lvNCz-0000R4-IM for patch@linaro.org; Mon, 21 Jun 2021 12:55:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:33526) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lvMnS-0007Wb-O0 for qemu-devel@nongnu.org; Mon, 21 Jun 2021 12:29:14 -0400 Received: from mail-wr1-x434.google.com ([2a00:1450:4864:20::434]:38416) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lvMnQ-0007hV-2m for qemu-devel@nongnu.org; Mon, 21 Jun 2021 12:29:14 -0400 Received: by mail-wr1-x434.google.com with SMTP id h11so2899241wrx.5 for ; Mon, 21 Jun 2021 09:29:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=/JCC4OyoVW6+mhRPcZdtNM8Y0F4eJiGOfrPF39mhaX8=; b=dvEb4+6ArWsKMU6hDTW6hMJLJCUFkvYcjpubGzzEb5wfWCJm7ZtTiNfrh3VClqevNF K2CU8B6d2k9YBgTKB7XNnodFgKVku7cb2lj4EBlvLCrHgedBweOIiu0njwllqtYKfPXg HKyfDS/nzc/xTs1Rw03KRQm3qHE2rk7pPzxCjdzqvez4+cauhfj9YFxSRaBrEhUp7r0t kdmdoo4liFyjp/sk8ZFQM5pEgt7fUatof9+Xe0o+4j0mTy3LXOvis7hqY2m7IbwzwiS0 omPmDKVKNWDPa4/WjaA5N/e3u+5PeisvejKC2eN9tDyU5nk65qX3apAQ9BiHh9tthNOH M6Lg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/JCC4OyoVW6+mhRPcZdtNM8Y0F4eJiGOfrPF39mhaX8=; b=tRiy/o8xxBSyDWPoRDqmnlHfsZvX6nvtTYgmHRApzAVJGpdV0h7RMRNHnLty+ozS5K mJtEkuEeHUHIE0j6OBbXzxRq+ePVUs1pVnmSVH7Ct3wFHVndM3DfRw3oCGg+CABb+7PX tdEZqOUE4PNI6I0pw4BW10lXMr8ipGxlXIBC3Kv9NpQ0NMHWx+H8bajtvBeILHY/0BJL y1y+VeoWP7vkAje7zzfibZ68EBpaqjDVRP8G26ikg+C2lWFCSo1AQLdmYcmmEDEN4sSo jP3ny0s4nO2B6zI2v3RKazqAD94bcv84HXOP13s9YVleatALxzVr5l4EV2H1J0BrUMWO 1j7w== X-Gm-Message-State: AOAM53201AC7BVpE7f0ZZgv8I2y/YfYXmoe1LdWIIoVHmUbsf9/vLyRZ SafRESLl3514ERWpzMD3SccxI/RTWTu8wEyA X-Received: by 2002:adf:d1e5:: with SMTP id g5mr10141016wrd.0.1624292950718; Mon, 21 Jun 2021 09:29:10 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id n65sm11615496wme.21.2021.06.21.09.29.09 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Jun 2021 09:29:10 -0700 (PDT) From: Peter Maydell To: qemu-devel@nongnu.org Subject: [PULL 38/57] target/arm: Implement MVE VQADD and VQSUB Date: Mon, 21 Jun 2021 17:28:14 +0100 Message-Id: <20210621162833.32535-39-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210621162833.32535-1-peter.maydell@linaro.org> References: <20210621162833.32535-1-peter.maydell@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::434; envelope-from=peter.maydell@linaro.org; helo=mail-wr1-x434.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, 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: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Implement the MVE VQADD and VQSUB insns, which perform saturating addition of a scalar to each element. Note that individual bytes of each result element are used or discarded according to the predicate mask, but FPSCR.QC is only set if the predicate mask for the lowest byte of the element is set. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20210617121628.20116-28-peter.maydell@linaro.org --- target/arm/helper-mve.h | 16 ++++++++++ target/arm/mve.decode | 5 +++ target/arm/mve_helper.c | 62 ++++++++++++++++++++++++++++++++++++++ target/arm/translate-mve.c | 4 +++ 4 files changed, 87 insertions(+) -- 2.20.1 diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h index 1b807e1cf5f..092efdab475 100644 --- a/target/arm/helper-mve.h +++ b/target/arm/helper-mve.h @@ -173,6 +173,22 @@ DEF_HELPER_FLAGS_4(mve_vhsubu_scalarb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) DEF_HELPER_FLAGS_4(mve_vhsubu_scalarh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) DEF_HELPER_FLAGS_4(mve_vhsubu_scalarw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(mve_vqadds_scalarb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(mve_vqadds_scalarh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(mve_vqadds_scalarw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) + +DEF_HELPER_FLAGS_4(mve_vqaddu_scalarb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(mve_vqaddu_scalarh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(mve_vqaddu_scalarw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) + +DEF_HELPER_FLAGS_4(mve_vqsubs_scalarb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(mve_vqsubs_scalarh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(mve_vqsubs_scalarw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) + +DEF_HELPER_FLAGS_4(mve_vqsubu_scalarb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(mve_vqsubu_scalarh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(mve_vqsubu_scalarw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) + DEF_HELPER_FLAGS_4(mve_vbrsrb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) DEF_HELPER_FLAGS_4(mve_vbrsrh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) DEF_HELPER_FLAGS_4(mve_vbrsrw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) diff --git a/target/arm/mve.decode b/target/arm/mve.decode index e189e2de648..c85227c675a 100644 --- a/target/arm/mve.decode +++ b/target/arm/mve.decode @@ -167,6 +167,11 @@ VHADD_S_scalar 1110 1110 0 . .. ... 0 ... 0 1111 . 100 .... @2scalar VHADD_U_scalar 1111 1110 0 . .. ... 0 ... 0 1111 . 100 .... @2scalar VHSUB_S_scalar 1110 1110 0 . .. ... 0 ... 1 1111 . 100 .... @2scalar VHSUB_U_scalar 1111 1110 0 . .. ... 0 ... 1 1111 . 100 .... @2scalar + +VQADD_S_scalar 1110 1110 0 . .. ... 0 ... 0 1111 . 110 .... @2scalar +VQADD_U_scalar 1111 1110 0 . .. ... 0 ... 0 1111 . 110 .... @2scalar +VQSUB_S_scalar 1110 1110 0 . .. ... 0 ... 1 1111 . 110 .... @2scalar +VQSUB_U_scalar 1111 1110 0 . .. ... 0 ... 1 1111 . 110 .... @2scalar VBRSR 1111 1110 0 . .. ... 1 ... 1 1110 . 110 .... @2scalar # Predicate operations diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c index 558c6f5aa34..1d97bd2ae84 100644 --- a/target/arm/mve_helper.c +++ b/target/arm/mve_helper.c @@ -490,6 +490,33 @@ DO_2OP_U(vhaddu, do_vhadd_u) DO_2OP_S(vhsubs, do_vhsub_s) DO_2OP_U(vhsubu, do_vhsub_u) +static inline int32_t do_sat_bhw(int64_t val, int64_t min, int64_t max, bool *s) +{ + if (val > max) { + *s = true; + return max; + } else if (val < min) { + *s = true; + return min; + } + return val; +} + +#define DO_SQADD_B(n, m, s) do_sat_bhw((int64_t)n + m, INT8_MIN, INT8_MAX, s) +#define DO_SQADD_H(n, m, s) do_sat_bhw((int64_t)n + m, INT16_MIN, INT16_MAX, s) +#define DO_SQADD_W(n, m, s) do_sat_bhw((int64_t)n + m, INT32_MIN, INT32_MAX, s) + +#define DO_UQADD_B(n, m, s) do_sat_bhw((int64_t)n + m, 0, UINT8_MAX, s) +#define DO_UQADD_H(n, m, s) do_sat_bhw((int64_t)n + m, 0, UINT16_MAX, s) +#define DO_UQADD_W(n, m, s) do_sat_bhw((int64_t)n + m, 0, UINT32_MAX, s) + +#define DO_SQSUB_B(n, m, s) do_sat_bhw((int64_t)n - m, INT8_MIN, INT8_MAX, s) +#define DO_SQSUB_H(n, m, s) do_sat_bhw((int64_t)n - m, INT16_MIN, INT16_MAX, s) +#define DO_SQSUB_W(n, m, s) do_sat_bhw((int64_t)n - m, INT32_MIN, INT32_MAX, s) + +#define DO_UQSUB_B(n, m, s) do_sat_bhw((int64_t)n - m, 0, UINT8_MAX, s) +#define DO_UQSUB_H(n, m, s) do_sat_bhw((int64_t)n - m, 0, UINT16_MAX, s) +#define DO_UQSUB_W(n, m, s) do_sat_bhw((int64_t)n - m, 0, UINT32_MAX, s) #define DO_2OP_SCALAR(OP, ESIZE, TYPE, FN) \ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, void *vn, \ @@ -505,6 +532,27 @@ DO_2OP_U(vhsubu, do_vhsub_u) mve_advance_vpt(env); \ } +#define DO_2OP_SAT_SCALAR(OP, ESIZE, TYPE, FN) \ + void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, void *vn, \ + uint32_t rm) \ + { \ + TYPE *d = vd, *n = vn; \ + TYPE m = rm; \ + uint16_t mask = mve_element_mask(env); \ + unsigned e; \ + bool qc = false; \ + for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \ + bool sat = false; \ + mergemask(&d[H##ESIZE(e)], FN(n[H##ESIZE(e)], m, &sat), \ + mask); \ + qc |= sat & mask & 1; \ + } \ + if (qc) { \ + env->vfp.qc[0] = qc; \ + } \ + mve_advance_vpt(env); \ + } + /* provide unsigned 2-op scalar helpers for all sizes */ #define DO_2OP_SCALAR_U(OP, FN) \ DO_2OP_SCALAR(OP##b, 1, uint8_t, FN) \ @@ -523,6 +571,20 @@ DO_2OP_SCALAR_U(vhaddu_scalar, do_vhadd_u) DO_2OP_SCALAR_S(vhsubs_scalar, do_vhsub_s) DO_2OP_SCALAR_U(vhsubu_scalar, do_vhsub_u) +DO_2OP_SAT_SCALAR(vqaddu_scalarb, 1, uint8_t, DO_UQADD_B) +DO_2OP_SAT_SCALAR(vqaddu_scalarh, 2, uint16_t, DO_UQADD_H) +DO_2OP_SAT_SCALAR(vqaddu_scalarw, 4, uint32_t, DO_UQADD_W) +DO_2OP_SAT_SCALAR(vqadds_scalarb, 1, int8_t, DO_SQADD_B) +DO_2OP_SAT_SCALAR(vqadds_scalarh, 2, int16_t, DO_SQADD_H) +DO_2OP_SAT_SCALAR(vqadds_scalarw, 4, int32_t, DO_SQADD_W) + +DO_2OP_SAT_SCALAR(vqsubu_scalarb, 1, uint8_t, DO_UQSUB_B) +DO_2OP_SAT_SCALAR(vqsubu_scalarh, 2, uint16_t, DO_UQSUB_H) +DO_2OP_SAT_SCALAR(vqsubu_scalarw, 4, uint32_t, DO_UQSUB_W) +DO_2OP_SAT_SCALAR(vqsubs_scalarb, 1, int8_t, DO_SQSUB_B) +DO_2OP_SAT_SCALAR(vqsubs_scalarh, 2, int16_t, DO_SQSUB_H) +DO_2OP_SAT_SCALAR(vqsubs_scalarw, 4, int32_t, DO_SQSUB_W) + static inline uint32_t do_vbrsrb(uint32_t n, uint32_t m) { m &= 0xff; diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c index 7c4c06e434c..27c69d9c7dd 100644 --- a/target/arm/translate-mve.c +++ b/target/arm/translate-mve.c @@ -446,6 +446,10 @@ DO_2OP_SCALAR(VHADD_S_scalar, vhadds_scalar) DO_2OP_SCALAR(VHADD_U_scalar, vhaddu_scalar) DO_2OP_SCALAR(VHSUB_S_scalar, vhsubs_scalar) DO_2OP_SCALAR(VHSUB_U_scalar, vhsubu_scalar) +DO_2OP_SCALAR(VQADD_S_scalar, vqadds_scalar) +DO_2OP_SCALAR(VQADD_U_scalar, vqaddu_scalar) +DO_2OP_SCALAR(VQSUB_S_scalar, vqsubs_scalar) +DO_2OP_SCALAR(VQSUB_U_scalar, vqsubu_scalar) DO_2OP_SCALAR(VBRSR, vbrsr) static bool do_long_dual_acc(DisasContext *s, arg_vmlaldav *a,