From nobody Tue Feb 10 05:39:58 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; 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 ARC-Seal: i=1; a=rsa-sha256; t=1561310657; cv=none; d=zoho.com; s=zohoarc; b=kzjEzDrIlvkCVaAxROQUwNSADYrktOq0DdsqnkToUDE3NLbNBEok0C9rscoE2jHGg3JhzUVviG6lAWKNTIkIPxcXW8zEXlxsTDbtJLO18yR6PqZBnwbFH30LyD59Ywx7bs2I5CW5MZ2IyyHfqFDMqohstppX54Rv0BM7DaPPpoA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1561310657; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=mC/nNt4052R5bDPIq7NTVsOCxyETmKyKCMce/+Totvg=; b=FzTAblqtRiE5Gif5LCEUP7xJBABr6EHlrtPc85Oq+itAwraN8ZaLI4epVf2FbGhaFpVBFDN0dj5hdNGHwaGWuahtnMzrcm7prNjPFkr1wkVOpsMRqrH4zdudn14ioft0iC0wKa4JlHdY+Z9chA3iHWHsmk40mDUR1FmVmd3UFCw= ARC-Authentication-Results: i=1; mx.zoho.com; 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 Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1561310657733247.8420722501636; Sun, 23 Jun 2019 10:24:17 -0700 (PDT) Received: from localhost ([::1]:45896 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hf6Dr-0007it-MK for importer@patchew.org; Sun, 23 Jun 2019 13:24:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:34344) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hf5wk-0001oN-TO for qemu-devel@nongnu.org; Sun, 23 Jun 2019 13:06:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hf5wg-0004rl-UM for qemu-devel@nongnu.org; Sun, 23 Jun 2019 13:06:30 -0400 Received: from mx2.rt-rk.com ([89.216.37.149]:41132 helo=mail.rt-rk.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hf5wc-0004JZ-2Z for qemu-devel@nongnu.org; Sun, 23 Jun 2019 13:06:24 -0400 Received: from localhost (localhost [127.0.0.1]) by mail.rt-rk.com (Postfix) with ESMTP id EAD8E1A1DEC; Sun, 23 Jun 2019 19:05:45 +0200 (CEST) Received: from rtrkw774-lin.domain.local (rtrkw774-lin.domain.local [10.10.13.43]) by mail.rt-rk.com (Postfix) with ESMTPSA id B8C0D1A1DDA; Sun, 23 Jun 2019 19:05:45 +0200 (CEST) X-Virus-Scanned: amavisd-new at rt-rk.com From: Aleksandar Markovic To: qemu-devel@nongnu.org Date: Sun, 23 Jun 2019 19:04:49 +0200 Message-Id: <1561309489-16146-17-git-send-email-aleksandar.markovic@rt-rk.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1561309489-16146-1-git-send-email-aleksandar.markovic@rt-rk.com> References: <1561309489-16146-1-git-send-email-aleksandar.markovic@rt-rk.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 89.216.37.149 Subject: [Qemu-devel] [PATCH v5 16/16] tcg/ppc: Update vector support to v3.00 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: , Cc: richard.henderson@linaro.org, "David Gibson --cc=amarkovic @ wavecomp . com" , Mark Cave-Ayland , Aleksandar Markovic , hsp.cat7@gmail.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Richard Henderson This includes vector load/store with immediate offset, some extra move and splat insns, compare ne, and negate. Signed-off-by: Richard Henderson Signed-off-by: Aleksandar Markovic --- tcg/ppc/tcg-target.h | 3 +- tcg/ppc/tcg-target.inc.c | 103 ++++++++++++++++++++++++++++++++++++++++++-= ---- 2 files changed, 94 insertions(+), 12 deletions(-) diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h index b8355d0..533f0ef 100644 --- a/tcg/ppc/tcg-target.h +++ b/tcg/ppc/tcg-target.h @@ -63,6 +63,7 @@ extern bool have_isa_2_06; extern bool have_isa_2_06_vsx; 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 */ @@ -150,7 +151,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_abs_vec 0 #define TCG_TARGET_HAS_shi_vec 0 #define TCG_TARGET_HAS_shs_vec 0 diff --git a/tcg/ppc/tcg-target.inc.c b/tcg/ppc/tcg-target.inc.c index badbe2c..6cc56cf 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(57) | 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) @@ -589,11 +601,14 @@ static int tcg_target_const_match(tcg_target_long val= , TCGType type, =20 #define XXPERMDI (OPCD(60) | (10 << 3)) /* v2.06 */ #define XXSEL (OPCD(60) | (3 << 4)) /* 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) @@ -917,6 +932,10 @@ static void tcg_out_dupi_vec(TCGContext *s, TCGType ty= pe, TCGReg ret, return; } } + 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; + } =20 /* * Otherwise we must load the value from the constant pool. @@ -1105,7 +1124,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) { @@ -1118,11 +1137,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 @@ -1131,7 +1159,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; @@ -1195,7 +1223,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); @@ -1207,7 +1236,8 @@ static void tcg_out_ld(TCGContext *s, TCGType type, T= CGReg ret, case TCG_TYPE_V128: tcg_debug_assert(ret >=3D 32); assert((offset & 15) =3D=3D 0); - 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(); @@ -1246,7 +1276,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); @@ -1259,7 +1290,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(); @@ -2970,6 +3002,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: @@ -2990,7 +3024,22 @@ static bool tcg_out_dup_vec(TCGContext *s, TCGType t= ype, unsigned vece, TCGReg dst, TCGReg src) { tcg_debug_assert(dst >=3D 32); - tcg_debug_assert(src >=3D 32); + + /* Splat from integer reg allowed via constraints for v3.00. */ + if (src < 32) { + tcg_debug_assert(have_isa_3_00_vsx); + switch (vece) { + case MO_64: + tcg_out32(s, MTVSRDD | 1 | VRT(dst) | RA(src) | RB(src)); + return true; + case MO_32: + tcg_out32(s, MTVSRWS | 1 | VRT(dst) | RA(src)); + return true; + default: + /* Fail, so that we fall back on either dupm or mov+dup. */ + return false; + } + } =20 /* * Recall we use (or emulate) VSX integer loads, so the integer is @@ -3029,7 +3078,11 @@ static bool tcg_out_dupm_vec(TCGContext *s, TCGType = type, unsigned vece, out &=3D 31; switch (vece) { case MO_8: - tcg_out_mem_long(s, 0, LVEBX, out, base, offset); + if (have_isa_3_00_vsx) { + tcg_out_mem_long(s, LXV | 8, LVX, out, base, offset & -16); + } else { + tcg_out_mem_long(s, 0, LVEBX, out, base, offset); + } elt =3D extract32(offset, 0, 4); #ifndef HOST_WORDS_BIGENDIAN elt ^=3D 15; @@ -3038,7 +3091,11 @@ static bool tcg_out_dupm_vec(TCGContext *s, TCGType = type, unsigned vece, break; case MO_16: assert((offset & 1) =3D=3D 0); - tcg_out_mem_long(s, 0, LVEHX, out, base, offset); + if (have_isa_3_00_vsx) { + tcg_out_mem_long(s, LXV | 8, LVX, out, base, offset & -16); + } else { + tcg_out_mem_long(s, 0, LVEHX, out, base, offset); + } elt =3D extract32(offset, 1, 3); #ifndef HOST_WORDS_BIGENDIAN elt ^=3D 7; @@ -3046,6 +3103,10 @@ static bool tcg_out_dupm_vec(TCGContext *s, TCGType = type, unsigned vece, 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); @@ -3085,7 +3146,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 }, @@ -3127,6 +3190,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; @@ -3189,6 +3257,9 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode o= pc, 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; @@ -3271,6 +3342,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; @@ -3426,6 +3501,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpc= ode op) static const TCGTargetOpDef sub2 =3D { .args_ct_str =3D { "r", "r", "rI", "rZM", "r", "r" } }; static const TCGTargetOpDef v_r =3D { .args_ct_str =3D { "v", "r" } }; + static const TCGTargetOpDef v_vr =3D { .args_ct_str =3D { "v", "vr" } = }; static const TCGTargetOpDef v_v =3D { .args_ct_str =3D { "v", "v" } }; static const TCGTargetOpDef v_v_v =3D { .args_ct_str =3D { "v", "v", "= v" } }; static const TCGTargetOpDef v_v_v_v @@ -3594,8 +3670,10 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOp= code op) case INDEX_op_dup2_vec: return &v_v_v; case INDEX_op_not_vec: - case INDEX_op_dup_vec: + case INDEX_op_neg_vec: return &v_v; + case INDEX_op_dup_vec: + return have_isa_3_00_vsx ? &v_vr : &v_v; case INDEX_op_ld_vec: case INDEX_op_st_vec: case INDEX_op_dupm_vec: @@ -3631,6 +3709,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.7.4