From nobody Mon Feb 9 11:21:26 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.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; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.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=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1552814471150876.2209292906066; Sun, 17 Mar 2019 02:21:11 -0700 (PDT) Received: from localhost ([127.0.0.1]:52257 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h5Ryd-00078J-4p for importer@patchew.org; Sun, 17 Mar 2019 05:21:07 -0400 Received: from eggs.gnu.org ([209.51.188.92]:47787) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h5Rms-0005pE-JA for qemu-devel@nongnu.org; Sun, 17 Mar 2019 05:09:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h5Rmq-0004F1-EO for qemu-devel@nongnu.org; Sun, 17 Mar 2019 05:08:58 -0400 Received: from mail-pg1-x52f.google.com ([2607:f8b0:4864:20::52f]:35669) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1h5Rmp-0004Ec-Tm for qemu-devel@nongnu.org; Sun, 17 Mar 2019 05:08:56 -0400 Received: by mail-pg1-x52f.google.com with SMTP id e17so9338414pgd.2 for ; Sun, 17 Mar 2019 02:08:55 -0700 (PDT) Received: from cloudburst.twiddle.net (97-113-188-82.tukw.qwest.net. [97.113.188.82]) by smtp.gmail.com with ESMTPSA id b85sm19378435pfj.56.2019.03.17.02.08.53 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 17 Mar 2019 02:08:53 -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; bh=UbUHjOGFvH6dTe8Kp5jjIczIrR/W8mET9OY/qeHuZ2A=; b=vrpfvTcLobNj/PqyCJQ7Ulrj8KDSFH0lVSm6E4pPy0B6ejaCcZ+qhe7eeXxorrhlzN LutT9W7lUXra0twpHrhff7e0bDSl6KfMb4a/vxmCK5yqIz6Jh0xqUnmePkOmEsWQy+mp hqYkVVT6ngj/VZra03fSG/YRycG3b/TmTigkImtyBUXt4OyOxnQdNO3Mh5OFNy/UHZgq 3K86WsKhq7L1sdg/dmvXqFsKojQ5/wJ+td0hKUk6kz9+Abq6lRSj0Ikc3ymU/uBGprVf J3zjXC1fjFE3yypmMWjJugzXHh4tU2UYBT5gjthraDNV99ZfCgufYznndrhJ37dRNLNB 56nw== 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; bh=UbUHjOGFvH6dTe8Kp5jjIczIrR/W8mET9OY/qeHuZ2A=; b=DhUSeEDb/swq+Fxn8iiCYoH6oN1cSLNGk+AnO+6LKtfWD10RvJV5pxbmBs/fldVWwp gzsYkvovuUGrThsdMrk5D16qeKlzAtxgVLZ37hagaLDgB41ulrd1uRyfomlY+2e7mmLb w/6FeMxiKQzwaCVBvaLsP63MsSrA4shryEQuQZ1j50rbmhiAh1TvNizK/Za7HiQxAlIn Rl43BkrZnSr/cu9Jzn8fYHZ47rpPcdkGzNC+HmWcXNcYg+k4f0opGqRppImSthglSWRV 8vFudT4Iu4PGIJiDLaF2f4u7VhEnzifKJcB1F+kYCLyGNd5DJdZjabG58C7haVqF4uGG dOzA== X-Gm-Message-State: APjAAAUgehBG8RN7r09+sRBYbEO3PZj3H5rzJ1TS7yTVPyaERL/53Yiw jYxVxku6AoHRc5y1qGzrX2iz0r0g/RE= X-Google-Smtp-Source: APXvYqxOhOwp7GA45kGUNkG2JCuGq4iNxPC09xFSY5M61/Gwcky6S9UyywtfGARbMuEFgA8UIza5RQ== X-Received: by 2002:a65:4203:: with SMTP id c3mr12241574pgq.271.1552813734553; Sun, 17 Mar 2019 02:08:54 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sun, 17 Mar 2019 02:08:34 -0700 Message-Id: <20190317090834.5552-14-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190317090834.5552-1-richard.henderson@linaro.org> References: <20190317090834.5552-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::52f Subject: [Qemu-devel] [PATCH for-4.1 v2 13/13] tcg/ppc: Update vector support to v3.00 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: mark.cave-ayland@ilande.co.uk, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This includes vector load/store with immediate offset, some extra move and splat insns, compare ne, and negate. Signed-off-by: Richard Henderson --- tcg/ppc/tcg-target.h | 3 +- tcg/ppc/tcg-target.inc.c | 115 +++++++++++++++++++++++++++++---------- 2 files changed, 89 insertions(+), 29 deletions(-) diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h index 4bbb33df7e..2babcff45f 100644 --- a/tcg/ppc/tcg-target.h +++ b/tcg/ppc/tcg-target.h @@ -62,6 +62,7 @@ extern bool have_isa_altivec; extern bool have_isa_2_06; extern bool have_isa_2_07_vsx; extern bool have_isa_3_00; +extern bool have_isa_3_00_vsx; =20 /* optional instructions automatically implemented */ #define TCG_TARGET_HAS_ext8u_i32 0 /* andi */ @@ -145,7 +146,7 @@ extern bool have_isa_3_00; #define TCG_TARGET_HAS_andc_vec 1 #define TCG_TARGET_HAS_orc_vec have_isa_2_07_vsx #define TCG_TARGET_HAS_not_vec 1 -#define TCG_TARGET_HAS_neg_vec 0 +#define TCG_TARGET_HAS_neg_vec have_isa_3_00_vsx #define TCG_TARGET_HAS_shi_vec 0 #define TCG_TARGET_HAS_shs_vec 0 #define TCG_TARGET_HAS_shv_vec 1 diff --git a/tcg/ppc/tcg-target.inc.c b/tcg/ppc/tcg-target.inc.c index b8df9b55cf..3e99d3cadb 100644 --- a/tcg/ppc/tcg-target.inc.c +++ b/tcg/ppc/tcg-target.inc.c @@ -69,6 +69,7 @@ bool have_isa_2_06; bool have_isa_2_06_vsx; bool have_isa_2_07_vsx; bool have_isa_3_00; +bool have_isa_3_00_vsx; =20 #define HAVE_ISA_2_06 have_isa_2_06 #define HAVE_ISEL have_isa_2_06 @@ -475,11 +476,16 @@ static int tcg_target_const_match(tcg_target_long val= , TCGType type, #define LXSDX XO31(588) /* v2.06 */ #define LXVDSX XO31(332) /* v2.06 */ #define LXSIWZX XO31(12) /* v2.07 */ +#define LXV (OPCD(61) | 1) /* v3.00 */ +#define LXSD (OPCD(51) | 2) /* v3.00 */ +#define LXVWSX XO31(364) /* v3.00 */ =20 #define STVX XO31(231) #define STVEWX XO31(199) #define STXSDX XO31(716) /* v2.06 */ #define STXSIWX XO31(140) /* v2.07 */ +#define STXV (OPCD(61) | 5) /* v3.00 */ +#define STXSD (OPCD(61) | 2) /* v3.00 */ =20 #define VADDSBS VX4(768) #define VADDUBS VX4(512) @@ -503,6 +509,9 @@ static int tcg_target_const_match(tcg_target_long val, = TCGType type, #define VSUBUWM VX4(1152) #define VSUBUDM VX4(1216) /* v2.07 */ =20 +#define VNEGW (VX4(1538) | (6 << 16)) /* v3.00 */ +#define VNEGD (VX4(1538) | (7 << 16)) /* v3.00 */ + #define VMAXSB VX4(258) #define VMAXSH VX4(322) #define VMAXSW VX4(386) @@ -532,6 +541,9 @@ static int tcg_target_const_match(tcg_target_long val, = TCGType type, #define VCMPGTUH VX4(582) #define VCMPGTUW VX4(646) #define VCMPGTUD VX4(711) /* v2.07 */ +#define VCMPNEB VX4(7) /* v3.00 */ +#define VCMPNEH VX4(71) /* v3.00 */ +#define VCMPNEW VX4(135) /* v3.00 */ =20 #define VSLB VX4(260) #define VSLH VX4(324) @@ -588,12 +600,15 @@ static int tcg_target_const_match(tcg_target_long val= , TCGType type, #define VPERM VX4(43) #define VSLDOI VX4(44) =20 -#define XXPERMDI (OPCD(60) | (10 << 3)) /* 2.06 */ +#define XXPERMDI (OPCD(60) | (10 << 3)) /* v2.06 */ +#define XXSPLTIB (OPCD(60) | (360 << 1)) /* v3.00 */ =20 #define MFVSRD XO31(51) /* v2.07 */ #define MFVSRWZ XO31(115) /* v2.07 */ #define MTVSRD XO31(179) /* v2.07 */ #define MTVSRWZ XO31(179) /* v2.07 */ +#define MTVSRDD XO31(435) /* v3.00 */ +#define MTVSRWS XO31(403) /* v3.00 */ =20 #define RT(r) ((r)<<21) #define RS(r) ((r)<<21) @@ -931,6 +946,11 @@ static void tcg_out_dupi_vec(TCGContext *s, TCGType ty= pe, TCGReg ret, } } =20 + if (have_isa_3_00_vsx && val =3D=3D (tcg_target_long)dup_const(MO_8, v= al)) { + tcg_out32(s, XXSPLTIB | VRT(ret) | ((val & 0xff) << 11) | 1); + return; + } + /* With Altivec, we load the whole 128-bit value. */ tcg_out_imm_vec(s, ret, val, val); } @@ -1084,7 +1104,7 @@ static void tcg_out_mem_long(TCGContext *s, int opi, = int opx, TCGReg rt, TCGReg base, tcg_target_long offset) { tcg_target_long orig =3D offset, l0, l1, extra =3D 0, align =3D 0; - bool is_store =3D false; + bool is_int_store =3D false; TCGReg rs =3D TCG_REG_TMP1; =20 switch (opi) { @@ -1097,11 +1117,20 @@ static void tcg_out_mem_long(TCGContext *s, int opi= , int opx, TCGReg rt, break; } break; + case LXSD: + case STXSD: + align =3D 3; + break; + case LXV: case LXV | 8: + case STXV: case STXV | 8: + /* The |8 cases force altivec registers. */ + align =3D 15; + break; case STD: align =3D 3; /* FALLTHRU */ case STB: case STH: case STW: - is_store =3D true; + is_int_store =3D true; break; } =20 @@ -1110,7 +1139,7 @@ static void tcg_out_mem_long(TCGContext *s, int opi, = int opx, TCGReg rt, if (rs =3D=3D base) { rs =3D TCG_REG_R0; } - tcg_debug_assert(!is_store || rs !=3D rt); + tcg_debug_assert(!is_int_store || rs !=3D rt); tcg_out_movi(s, TCG_TYPE_PTR, rs, orig); tcg_out32(s, opx | TAB(rt, base, rs)); return; @@ -1169,7 +1198,8 @@ static void tcg_out_ld(TCGContext *s, TCGType type, T= CGReg ret, case TCG_TYPE_V64: tcg_debug_assert(ret >=3D 32); if (have_isa_2_06_vsx) { - tcg_out_mem_long(s, 0, LXSDX | 1, ret & 31, base, offset); + tcg_out_mem_long(s, have_isa_3_00_vsx ? LXSD : 0, LXSDX | 1, + ret & 31, base, offset); break; } assert((offset & 7) =3D=3D 0); @@ -1180,7 +1210,8 @@ static void tcg_out_ld(TCGContext *s, TCGType type, T= CGReg ret, break; case TCG_TYPE_V128: tcg_debug_assert(ret >=3D 32); - tcg_out_mem_long(s, 0, LVX, ret & 31, base, offset); + tcg_out_mem_long(s, have_isa_3_00_vsx ? LXV | 8 : 0, LVX, + ret & 31, base, offset); break; default: g_assert_not_reached(); @@ -1220,7 +1251,8 @@ static void tcg_out_st(TCGContext *s, TCGType type, T= CGReg arg, case TCG_TYPE_V64: tcg_debug_assert(arg >=3D 32); if (have_isa_2_06_vsx) { - tcg_out_mem_long(s, 0, STXSDX | 1, arg & 31, base, offset); + tcg_out_mem_long(s, have_isa_3_00_vsx ? STXSD : 0, + STXSDX | 1, arg & 31, base, offset); break; } assert((offset & 7) =3D=3D 0); @@ -1234,7 +1266,8 @@ static void tcg_out_st(TCGContext *s, TCGType type, T= CGReg arg, break; case TCG_TYPE_V128: tcg_debug_assert(arg >=3D 32); - tcg_out_mem_long(s, 0, STVX, arg & 31, base, offset); + tcg_out_mem_long(s, have_isa_3_00_vsx ? STXV | 8 : 0, STVX, + arg & 31, base, offset); break; default: g_assert_not_reached(); @@ -2956,6 +2989,8 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, = unsigned vece) case INDEX_op_shri_vec: case INDEX_op_sari_vec: return vece <=3D MO_32 || have_isa_2_07_vsx ? -1 : 0; + case INDEX_op_neg_vec: + return vece >=3D MO_32 && have_isa_3_00_vsx; case INDEX_op_mul_vec: switch (vece) { case MO_8: @@ -2997,6 +3032,10 @@ static void tcg_out_dupm_vec(TCGContext *s, unsigned= vece, TCGReg out, tcg_out32(s, VSPLTH | VRT(out) | VRB(out) | (elt << 16)); break; case MO_32: + if (have_isa_3_00_vsx) { + tcg_out_mem_long(s, 0, LXVWSX | 1, out, base, offset); + break; + } assert((offset & 3) =3D=3D 0); tcg_out_mem_long(s, 0, LVEWX, out, base, offset); elt =3D extract32(offset, 2, 2); @@ -3032,7 +3071,9 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode o= pc, static const uint32_t add_op[4] =3D { VADDUBM, VADDUHM, VADDUWM, VADDUDM }, sub_op[4] =3D { VSUBUBM, VSUBUHM, VSUBUWM, VSUBUDM }, + neg_op[4] =3D { 0, 0, VNEGW, VNEGD }, eq_op[4] =3D { VCMPEQUB, VCMPEQUH, VCMPEQUW, VCMPEQUD }, + ne_op[4] =3D { VCMPNEB, VCMPNEH, VCMPNEW, 0 }, gts_op[4] =3D { VCMPGTSB, VCMPGTSH, VCMPGTSW, VCMPGTSD }, gtu_op[4] =3D { VCMPGTUB, VCMPGTUH, VCMPGTUW, VCMPGTUD }, ssadd_op[4] =3D { VADDSBS, VADDSHS, VADDSWS, 0 }, @@ -3073,6 +3114,11 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode = opc, case INDEX_op_sub_vec: insn =3D sub_op[vece]; break; + case INDEX_op_neg_vec: + insn =3D neg_op[vece]; + a2 =3D a1; + a1 =3D 0; + break; case INDEX_op_mul_vec: tcg_debug_assert(vece =3D=3D MO_32 && have_isa_2_07_vsx); insn =3D VMULUWM; @@ -3135,9 +3181,18 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode = opc, bool ok; switch (vece) { case MO_64: + if (have_isa_3_00_vsx) { + tcg_out32(s, MTVSRDD | 1 | VRT(a0) | RA(a1) | RB(a1)); + return; + } ok =3D tcg_out_mov(s, TCG_TYPE_I64, a0, a1); break; case MO_32: + if (have_isa_3_00_vsx) { + tcg_out32(s, MTVSRWS | 1 | VRT(a0) | RA(a1)); + return; + } + /* fall through */ case MO_16: case MO_8: ok =3D tcg_out_mov(s, TCG_TYPE_I32, a0, a1); @@ -3175,27 +3230,23 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode= opc, return; =20 case INDEX_op_cmp_vec: - { - TCGCond cond =3D args[3]; - - switch (cond) { - case TCG_COND_EQ: - insn =3D eq_op[vece]; - break; - case TCG_COND_GT: - insn =3D gts_op[vece]; - break; - case TCG_COND_GTU: - insn =3D gtu_op[vece]; - break; - default: - g_assert_not_reached(); - } - tcg_debug_assert(insn !=3D 0); - - tcg_out32(s, insn | VRT(a0) | VRA(a1) | VRB(a2)); + switch (args[3]) { + case TCG_COND_EQ: + insn =3D eq_op[vece]; + break; + case TCG_COND_NE: + insn =3D ne_op[vece]; + break; + case TCG_COND_GT: + insn =3D gts_op[vece]; + break; + case TCG_COND_GTU: + insn =3D gtu_op[vece]; + break; + default: + g_assert_not_reached(); } - return; + break; =20 case INDEX_op_ppc_mrgh_vec: insn =3D mrgh_op[vece]; @@ -3253,6 +3304,10 @@ static void expand_vec_cmp(TCGType type, unsigned ve= ce, TCGv_vec v0, case TCG_COND_GTU: break; case TCG_COND_NE: + if (have_isa_3_00_vsx && vece <=3D MO_32) { + break; + } + /* fall through */ case TCG_COND_LE: case TCG_COND_LEU: need_inv =3D true; @@ -3597,6 +3652,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpc= ode op) case INDEX_op_ppc_rotl_vec: return &v_v_v; case INDEX_op_not_vec: + case INDEX_op_neg_vec: return &v_v; case INDEX_op_dup_vec: return have_isa_2_07_vsx ? &v_vr : &v_v; @@ -3634,6 +3690,9 @@ static void tcg_target_init(TCGContext *s) #ifdef PPC_FEATURE2_ARCH_3_00 if (hwcap2 & PPC_FEATURE2_ARCH_3_00) { have_isa_3_00 =3D true; + if (hwcap & PPC_FEATURE_HAS_VSX) { + have_isa_3_00_vsx =3D true; + } } #endif =20 --=20 2.17.2