From nobody Sun Dec 14 06:17:03 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail header.i=@quicinc.com; spf=pass (zohomail.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=quicinc.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 162552889056167.69887151358137; Mon, 5 Jul 2021 16:48:10 -0700 (PDT) Received: from localhost ([::1]:40988 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m0YJt-0007l2-Fk for importer@patchew.org; Mon, 05 Jul 2021 19:48:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:35556) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m0Y7A-0003vs-L8 for qemu-devel@nongnu.org; Mon, 05 Jul 2021 19:35:00 -0400 Received: from alexa-out-sd-01.qualcomm.com ([199.106.114.38]:37367) by eggs.gnu.org with esmtps (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1m0Y76-0004gT-UE for qemu-devel@nongnu.org; Mon, 05 Jul 2021 19:35:00 -0400 Received: from unknown (HELO ironmsg05-sd.qualcomm.com) ([10.53.140.145]) by alexa-out-sd-01.qualcomm.com with ESMTP; 05 Jul 2021 16:34:39 -0700 Received: from vu-tsimpson-aus.qualcomm.com (HELO vu-tsimpson1-aus.qualcomm.com) ([10.222.150.1]) by ironmsg05-sd.qualcomm.com with ESMTP; 05 Jul 2021 16:34:38 -0700 Received: by vu-tsimpson1-aus.qualcomm.com (Postfix, from userid 47164) id 06CD21B03; Mon, 5 Jul 2021 18:34:38 -0500 (CDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1625528096; x=1657064096; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=g0Cy3SI2t3i6dR9wqAFDNAgs7AjCJ2R0XPjCmKegJXI=; b=fNLusQ6tPRKJHY+aGpYQ/sFMXTvhPOouoGFSkYYqq0B9k+z4CUiL6Mx1 TunTRuvUg+GAXPTvb/j03ppwKYeHVEjPU/sLhz6ro9vlBEjPkwkZCCf0d zw4dmqK8/hTCz3Bl+Om9O0+J+VZ8VdedhSiqSO+e1UBVIhKCw5P+e5tjx w=; X-QCInternal: smtphost From: Taylor Simpson To: qemu-devel@nongnu.org Subject: [PATCH 15/20] Hexagon HVX (target/hexagon) instruction decoding Date: Mon, 5 Jul 2021 18:34:29 -0500 Message-Id: <1625528074-19440-16-git-send-email-tsimpson@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1625528074-19440-1-git-send-email-tsimpson@quicinc.com> References: <1625528074-19440-1-git-send-email-tsimpson@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.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; Received-SPF: pass client-ip=199.106.114.38; envelope-from=tsimpson@qualcomm.com; helo=alexa-out-sd-01.qualcomm.com X-Spam_score_int: -40 X-Spam_score: -4.1 X-Spam_bar: ---- X-Spam_report: (-4.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, 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: , Cc: ale@rev.ng, peter.maydell@linaro.org, bcain@quicinc.com, richard.henderson@linaro.org, tsimpson@quicinc.com, philmd@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1625528892261100001 Add new file to target/hexagon/meson.build Signed-off-by: Taylor Simpson --- target/hexagon/mmvec/decode_ext_mmvec.h | 24 ++++ target/hexagon/decode.c | 24 +++- target/hexagon/mmvec/decode_ext_mmvec.c | 235 ++++++++++++++++++++++++++++= ++++ target/hexagon/meson.build | 1 + 4 files changed, 282 insertions(+), 2 deletions(-) create mode 100644 target/hexagon/mmvec/decode_ext_mmvec.h create mode 100644 target/hexagon/mmvec/decode_ext_mmvec.c diff --git a/target/hexagon/mmvec/decode_ext_mmvec.h b/target/hexagon/mmvec= /decode_ext_mmvec.h new file mode 100644 index 0000000..3664b68 --- /dev/null +++ b/target/hexagon/mmvec/decode_ext_mmvec.h @@ -0,0 +1,24 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Res= erved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef HEXAGON_DECODE_EXT_MMVEC_H +#define HEXAGON_DECODE_EXT_MMVEC_H + +void mmvec_ext_decode_checks(Packet *pkt, bool disas_only); +SlotMask mmvec_ext_decode_find_iclass_slots(int opcode); + +#endif diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c index d424245..653bfd7 100644 --- a/target/hexagon/decode.c +++ b/target/hexagon/decode.c @@ -22,6 +22,7 @@ #include "decode.h" #include "insn.h" #include "printinsn.h" +#include "mmvec/decode_ext_mmvec.h" =20 #define fZXTN(N, M, VAL) ((VAL) & ((1LL << (N)) - 1)) =20 @@ -566,8 +567,12 @@ static void decode_remove_extenders(Packet *packet) =20 static SlotMask get_valid_slots(const Packet *pkt, unsigned int slot) { - return find_iclass_slots(pkt->insn[slot].opcode, - pkt->insn[slot].iclass); + if (GET_ATTRIB(pkt->insn[slot].opcode, A_EXTENSION)) { + return mmvec_ext_decode_find_iclass_slots(pkt->insn[slot].opcode); + } else { + return find_iclass_slots(pkt->insn[slot].opcode, + pkt->insn[slot].iclass); + } } =20 #define DECODE_NEW_TABLE(TAG, SIZE, WHATNOT) /* NOTHING */ @@ -728,6 +733,11 @@ decode_insns_tablewalk(Insn *insn, const DectreeTable = *table, } decode_op(insn, opc, encoding); return 1; + } else if (table->table[i].type =3D=3D DECTREE_EXTSPACE) { + /* + * For now, HVX will be the only coproc + */ + return decode_insns_tablewalk(insn, ext_trees[EXT_IDX_mmvec], enco= ding); } else { return 0; } @@ -874,6 +884,7 @@ int decode_packet(int max_words, const uint32_t *words,= Packet *pkt, int words_read =3D 0; bool end_of_packet =3D false; int new_insns =3D 0; + int i; uint32_t encoding32; =20 /* Initialize */ @@ -901,6 +912,11 @@ int decode_packet(int max_words, const uint32_t *words= , Packet *pkt, return 0; } pkt->encod_pkt_size_in_bytes =3D words_read * 4; + pkt->pkt_has_hvx =3D false; + for (i =3D 0; i < num_insns; i++) { + pkt->pkt_has_hvx |=3D + GET_ATTRIB(pkt->insn[i].opcode, A_CVI); + } =20 /* * Check for :endloop in the parse bits @@ -931,6 +947,10 @@ int decode_packet(int max_words, const uint32_t *words= , Packet *pkt, decode_set_slot_number(pkt); decode_fill_newvalue_regno(pkt); =20 + if (pkt->pkt_has_hvx) { + mmvec_ext_decode_checks(pkt, disas_only); + } + if (!disas_only) { decode_shuffle_for_execution(pkt); decode_split_cmpjump(pkt); diff --git a/target/hexagon/mmvec/decode_ext_mmvec.c b/target/hexagon/mmvec= /decode_ext_mmvec.c new file mode 100644 index 0000000..b5b1bf1 --- /dev/null +++ b/target/hexagon/mmvec/decode_ext_mmvec.c @@ -0,0 +1,235 @@ +/* + * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Res= erved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "qemu/osdep.h" +#include "decode.h" +#include "opcodes.h" +#include "insn.h" +#include "iclass.h" +#include "mmvec/mmvec.h" +#include "mmvec/decode_ext_mmvec.h" + +static void +check_new_value(Packet *pkt) +{ + /* .new value for a MMVector store */ + int i, j; + const char *reginfo; + const char *destletters; + const char *dststr =3D NULL; + uint16_t def_opcode; + char letter; + int def_regnum; + + for (i =3D 1; i < pkt->num_insns; i++) { + uint16_t use_opcode =3D pkt->insn[i].opcode; + if (GET_ATTRIB(use_opcode, A_DOTNEWVALUE) && + GET_ATTRIB(use_opcode, A_CVI) && + GET_ATTRIB(use_opcode, A_STORE)) { + int use_regidx =3D strchr(opcode_reginfo[use_opcode], 's') - + opcode_reginfo[use_opcode]; + /* + * What's encoded at the N-field is the offset to who's produc= ing + * the value. + * Shift off the LSB which indicates odd/even register. + */ + int def_off =3D ((pkt->insn[i].regno[use_regidx]) >> 1); + int def_oreg =3D pkt->insn[i].regno[use_regidx] & 1; + int def_idx =3D -1; + for (j =3D i - 1; (j >=3D 0) && (def_off >=3D 0); j--) { + if (!GET_ATTRIB(pkt->insn[j].opcode, A_CVI)) { + continue; + } + def_off--; + if (def_off =3D=3D 0) { + def_idx =3D j; + break; + } + } + /* + * Check for a badly encoded N-field which points to an instru= ction + * out-of-range + */ + g_assert(!((def_off !=3D 0) || (def_idx < 0) || + (def_idx > (pkt->num_insns - 1)))); + + /* def_idx is the index of the producer */ + def_opcode =3D pkt->insn[def_idx].opcode; + reginfo =3D opcode_reginfo[def_opcode]; + destletters =3D "dexy"; + for (j =3D 0; (letter =3D destletters[j]) !=3D 0; j++) { + dststr =3D strchr(reginfo, letter); + if (dststr !=3D NULL) { + break; + } + } + if ((dststr =3D=3D NULL) && GET_ATTRIB(def_opcode, A_CVI_GATH= ER)) { + def_regnum =3D 0; + pkt->insn[i].regno[use_regidx] =3D def_oreg; + pkt->insn[i].new_value_producer_slot =3D pkt->insn[def_idx= ].slot; + } else { + if (dststr =3D=3D NULL) { + /* still not there, we have a bad packet */ + g_assert_not_reached(); + } + def_regnum =3D pkt->insn[def_idx].regno[dststr - reginfo]; + /* Now patch up the consumer with the register number */ + pkt->insn[i].regno[use_regidx] =3D def_regnum ^ def_oreg; + /* special case for (Vx,Vy) */ + dststr =3D strchr(reginfo, 'y'); + if (def_oreg && strchr(reginfo, 'x') && dststr) { + def_regnum =3D pkt->insn[def_idx].regno[dststr - regin= fo]; + pkt->insn[i].regno[use_regidx] =3D def_regnum; + } + /* + * We need to remember who produces this value to later + * check if it was dynamically cancelled + */ + pkt->insn[i].new_value_producer_slot =3D pkt->insn[def_idx= ].slot; + } + } + } +} + +/* + * We don't want to reorder slot1/slot0 with respect to each other. + * So in our shuffling, we don't want to move the .cur / .tmp vmem earlier + * Instead, we should move the producing instruction later + * But the producing instruction might feed a .new store! + * So we may need to move that even later. + */ + +static void +decode_mmvec_move_cvi_to_end(Packet *pkt, int max) +{ + int i; + for (i =3D 0; i < max; i++) { + if (GET_ATTRIB(pkt->insn[i].opcode, A_CVI)) { + int last_inst =3D pkt->num_insns - 1; + uint16_t last_opcode =3D pkt->insn[last_inst].opcode; + + /* + * If the last instruction is an endloop, move to the one befo= re it + * Keep endloop as the last thing always + */ + if ((last_opcode =3D=3D J2_endloop0) || + (last_opcode =3D=3D J2_endloop1) || + (last_opcode =3D=3D J2_endloop01)) { + last_inst--; + } + + decode_send_insn_to(pkt, i, last_inst); + max--; + i--; /* Retry this index now that packet has rotated */ + } + } +} + +static void +decode_shuffle_for_execution_vops(Packet *pkt) +{ + /* + * Sort for .new + */ + int i; + for (i =3D 0; i < pkt->num_insns; i++) { + uint16_t opcode =3D pkt->insn[i].opcode; + if (GET_ATTRIB(opcode, A_LOAD) && + (GET_ATTRIB(opcode, A_CVI_NEW) || + GET_ATTRIB(opcode, A_CVI_TMP))) { + /* + * Find prior consuming vector instructions + * Move to end of packet + */ + decode_mmvec_move_cvi_to_end(pkt, i); + break; + } + } + + /* Move HVX new value stores to the end of the packet */ + for (i =3D 0; i < pkt->num_insns - 1; i++) { + uint16_t opcode =3D pkt->insn[i].opcode; + if (GET_ATTRIB(opcode, A_STORE) && + GET_ATTRIB(opcode, A_CVI_NEW) && + !GET_ATTRIB(opcode, A_CVI_SCATTER_RELEASE)) { + int last_inst =3D pkt->num_insns - 1; + uint16_t last_opcode =3D pkt->insn[last_inst].opcode; + + /* + * If the last instruction is an endloop, move to the one befo= re it + * Keep endloop as the last thing always + */ + if ((last_opcode =3D=3D J2_endloop0) || + (last_opcode =3D=3D J2_endloop1) || + (last_opcode =3D=3D J2_endloop01)) { + last_inst--; + } + + decode_send_insn_to(pkt, i, last_inst); + break; + } + } +} + +static void +check_for_vhist(Packet *pkt) +{ + pkt->pkt_has_vhist =3D false; + for (int i =3D 0; i < pkt->num_insns; i++) { + int opcode =3D pkt->insn[i].opcode; + if (GET_ATTRIB(opcode, A_CVI) && GET_ATTRIB(opcode, A_CVI_4SLOT)) { + pkt->pkt_has_vhist =3D true; + return; + } + } +} + +/* + * Public Functions + */ + +SlotMask mmvec_ext_decode_find_iclass_slots(int opcode) +{ + if (GET_ATTRIB(opcode, A_CVI_VM)) { + /* HVX memory instruction */ + if (GET_ATTRIB(opcode, A_RESTRICT_SLOT0ONLY)) { + return SLOTS_0; + } else if (GET_ATTRIB(opcode, A_RESTRICT_SLOT1ONLY)) { + return SLOTS_1; + } + return SLOTS_01; + } else if (GET_ATTRIB(opcode, A_RESTRICT_SLOT2ONLY)) { + return SLOTS_2; + } else if (GET_ATTRIB(opcode, A_CVI_VX)) { + /* HVX multiply instruction */ + return SLOTS_23; + } else if (GET_ATTRIB(opcode, A_CVI_VS_VX)) { + /* HVX permute/shift instruction */ + return SLOTS_23; + } else { + return SLOTS_0123; + } +} + +void mmvec_ext_decode_checks(Packet *pkt, bool disas_only) +{ + check_new_value(pkt); + if (!disas_only) { + decode_shuffle_for_execution_vops(pkt); + } + check_for_vhist(pkt); +} diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build index ed292b4..e598c43 100644 --- a/target/hexagon/meson.build +++ b/target/hexagon/meson.build @@ -173,6 +173,7 @@ hexagon_ss.add(files( 'printinsn.c', 'arch.c', 'fma_emu.c', + 'mmvec/decode_ext_mmvec.c', 'mmvec/system_ext_mmvec.c', )) =20 --=20 2.7.4