From patchwork Sun Mar 17 09:08:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 160471 Delivered-To: patch@linaro.org Received: by 2002:a02:5cc1:0:0:0:0:0 with SMTP id w62csp1412057jad; Sun, 17 Mar 2019 02:21:31 -0700 (PDT) X-Google-Smtp-Source: APXvYqwC70YrqS/oS/HlfIww5QR4AEiTpsAa4xGlMxJzX8OG3eKQzFzzSlJVXwriAl5oEap/wzYL X-Received: by 2002:adf:f14f:: with SMTP id y15mr8608299wro.223.1552814491887; Sun, 17 Mar 2019 02:21:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1552814491; cv=none; d=google.com; s=arc-20160816; b=YGwKaQmhBn9mubBl0bcrkGiG3KTPaYEmdHZtXqPMCNapPcY8Q8Jci0j4v1uuyxXWo7 NhQ/cv5TK8U4Ayer109KeeHFzDWnxtNpdPnlYrfuVfKMQ3x1gp9aCJM9WpbdOIWlMf/P 5vkDoyuP/wQEmx/8SiHFNOQ6B+qJeVdAp5Fvp7Jj1HJtkULIRcLxG9XqoHKxMDWgCrgU YA5WrmG9NMUgdWfEfMuojLLQ+Gf7Cn0LkyNvBGxOAqmKyHdLkiEOb7mKjOZgcMpyPTxz XBgBKuM8b7AM/9N7R/A5LHhcCu2pmUB/hbymZSN5iTeb+jCxCIIjj3JotGQdN1Wi5sHw ik4A== 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:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=UbUHjOGFvH6dTe8Kp5jjIczIrR/W8mET9OY/qeHuZ2A=; b=ahLqmsDdmOoeCL5Gt30jxwuUmRxQzx+7YgFp4Oju00Q9ICpIpt/UEUMvo+foLeDxWX Pue7pqOwm9HI/ziSz+jv3QmcYeUjtsiirp+IwA9hfyQjKDgSAorEaSlIBwVp4QHRIsKB YWzO+TyTZTKjP3UT/6RWUQRZbJXReTj/xNHX7P/uWB4IWZImxFbd8KsMe4eXfFaV7Xmz kPJl6SzN+N07hMO3xZf6021roy7Kven1hbtysGoGY1AZrhnH6BpnpBXtrS6MrzdxjfJV ghfWBH13U1iYjcS7gFdwQlpaVayp35MaaN7kqerxR9PdqLaLT8eLX+iob7o8VqORY1p8 DcGw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=vrpfvTcL; 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=fail (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 y62si4219009wmg.2.2019.03.17.02.21.31 for (version=TLS1 cipher=AES128-SHA bits=128/128); Sun, 17 Mar 2019 02:21:31 -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=fail header.i=@linaro.org header.s=google header.b=vrpfvTcL; 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=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1]:52260 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h5Rz0-0007On-RM for patch@linaro.org; Sun, 17 Mar 2019 05:21:30 -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) 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-Received: by 2002:a65:4203:: with SMTP id c3mr12241574pgq.271.1552813734553; Sun, 17 Mar 2019 02:08:54 -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) 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+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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(-) -- 2.17.2 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; /* 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; #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 */ #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 */ #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 */ +#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 */ #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) -#define XXPERMDI (OPCD(60) | (10 << 3)) /* 2.06 */ +#define XXPERMDI (OPCD(60) | (10 << 3)) /* v2.06 */ +#define XXSPLTIB (OPCD(60) | (360 << 1)) /* v3.00 */ #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 */ #define RT(r) ((r)<<21) #define RS(r) ((r)<<21) @@ -931,6 +946,11 @@ static void tcg_out_dupi_vec(TCGContext *s, TCGType type, TCGReg ret, } } + if (have_isa_3_00_vsx && val == (tcg_target_long)dup_const(MO_8, val)) { + 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 = offset, l0, l1, extra = 0, align = 0; - bool is_store = false; + bool is_int_store = false; TCGReg rs = TCG_REG_TMP1; 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 = 3; + break; + case LXV: case LXV | 8: + case STXV: case STXV | 8: + /* The |8 cases force altivec registers. */ + align = 15; + break; case STD: align = 3; /* FALLTHRU */ case STB: case STH: case STW: - is_store = true; + is_int_store = true; break; } @@ -1110,7 +1139,7 @@ static void tcg_out_mem_long(TCGContext *s, int opi, int opx, TCGReg rt, if (rs == base) { rs = TCG_REG_R0; } - tcg_debug_assert(!is_store || rs != rt); + tcg_debug_assert(!is_int_store || rs != 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, TCGReg ret, case TCG_TYPE_V64: tcg_debug_assert(ret >= 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) == 0); @@ -1180,7 +1210,8 @@ static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, break; case TCG_TYPE_V128: tcg_debug_assert(ret >= 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, TCGReg arg, case TCG_TYPE_V64: tcg_debug_assert(arg >= 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) == 0); @@ -1234,7 +1266,8 @@ static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, break; case TCG_TYPE_V128: tcg_debug_assert(arg >= 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 <= MO_32 || have_isa_2_07_vsx ? -1 : 0; + case INDEX_op_neg_vec: + return vece >= 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) == 0); tcg_out_mem_long(s, 0, LVEWX, out, base, offset); elt = extract32(offset, 2, 2); @@ -3032,7 +3071,9 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, static const uint32_t add_op[4] = { VADDUBM, VADDUHM, VADDUWM, VADDUDM }, sub_op[4] = { VSUBUBM, VSUBUHM, VSUBUWM, VSUBUDM }, + neg_op[4] = { 0, 0, VNEGW, VNEGD }, eq_op[4] = { VCMPEQUB, VCMPEQUH, VCMPEQUW, VCMPEQUD }, + ne_op[4] = { VCMPNEB, VCMPNEH, VCMPNEW, 0 }, gts_op[4] = { VCMPGTSB, VCMPGTSH, VCMPGTSW, VCMPGTSD }, gtu_op[4] = { VCMPGTUB, VCMPGTUH, VCMPGTUW, VCMPGTUD }, ssadd_op[4] = { VADDSBS, VADDSHS, VADDSWS, 0 }, @@ -3073,6 +3114,11 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, case INDEX_op_sub_vec: insn = sub_op[vece]; break; + case INDEX_op_neg_vec: + insn = neg_op[vece]; + a2 = a1; + a1 = 0; + break; case INDEX_op_mul_vec: tcg_debug_assert(vece == MO_32 && have_isa_2_07_vsx); insn = 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 = 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 = tcg_out_mov(s, TCG_TYPE_I32, a0, a1); @@ -3175,27 +3230,23 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, return; case INDEX_op_cmp_vec: - { - TCGCond cond = args[3]; - - switch (cond) { - case TCG_COND_EQ: - insn = eq_op[vece]; - break; - case TCG_COND_GT: - insn = gts_op[vece]; - break; - case TCG_COND_GTU: - insn = gtu_op[vece]; - break; - default: - g_assert_not_reached(); - } - tcg_debug_assert(insn != 0); - - tcg_out32(s, insn | VRT(a0) | VRA(a1) | VRB(a2)); + switch (args[3]) { + case TCG_COND_EQ: + insn = eq_op[vece]; + break; + case TCG_COND_NE: + insn = ne_op[vece]; + break; + case TCG_COND_GT: + insn = gts_op[vece]; + break; + case TCG_COND_GTU: + insn = gtu_op[vece]; + break; + default: + g_assert_not_reached(); } - return; + break; case INDEX_op_ppc_mrgh_vec: insn = mrgh_op[vece]; @@ -3253,6 +3304,10 @@ static void expand_vec_cmp(TCGType type, unsigned vece, TCGv_vec v0, case TCG_COND_GTU: break; case TCG_COND_NE: + if (have_isa_3_00_vsx && vece <= MO_32) { + break; + } + /* fall through */ case TCG_COND_LE: case TCG_COND_LEU: need_inv = true; @@ -3597,6 +3652,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 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 = true; + if (hwcap & PPC_FEATURE_HAS_VSX) { + have_isa_3_00_vsx = true; + } } #endif