From nobody Tue Nov 26 20:36:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1704754186; cv=none; d=zohomail.com; s=zohoarc; b=hzh9eKsNIYwFVEMJQwL2I1DmqLP3TQz/UlxJuIdvNAWU0KlQlAkhAwuaVH8ET5LZt/T7cSBO986OBQkvZCDR0R1sY+jz/l8ybxQ+zp81Z3v3V034rMx0Ln/gTfpSuHNZdUFm2ceuZiAAymff9IM8ukqfy1K/Eob9qru4ldtAQD4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1704754186; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=ZOnoZQfKkD2ifAaIDL5GKWUQIzVug0CycBfx9jZ6Qvs=; b=XNdawtPvV7AX5VQCwbwWDeZWvtI1dLx1qa8OxAjbFMfhUDwIFbngjoxrtz1cSjyECvgzPXHxiNCAr9k4L8ZrbQdv9WEWi5fTr7jvDcAMYdaItD5Rd0Gr5Siez0s2svetarLy0XLg7gP6d5LTdH4OoqMkiJ0yc0Ta22GahFdyFAA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1704754186191978.4983795990853; Mon, 8 Jan 2024 14:49:46 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rMyQU-0006Wz-IR; Mon, 08 Jan 2024 17:48:58 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rMyQT-0006WV-0i for qemu-devel@nongnu.org; Mon, 08 Jan 2024 17:48:57 -0500 Received: from mail-il1-x129.google.com ([2607:f8b0:4864:20::129]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rMyQN-0008Uu-SH for qemu-devel@nongnu.org; Mon, 08 Jan 2024 17:48:56 -0500 Received: by mail-il1-x129.google.com with SMTP id e9e14a558f8ab-36066190a99so15167665ab.3 for ; Mon, 08 Jan 2024 14:48:51 -0800 (PST) Received: from taylor-ubuntu.hsd1.co.comcast.net (c-73-169-12-54.hsd1.co.comcast.net. [73.169.12.54]) by smtp.gmail.com with ESMTPSA id t7-20020a056638204700b0046e08e513b2sm241877jaj.116.2024.01.08.14.48.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Jan 2024 14:48:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1704754130; x=1705358930; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ZOnoZQfKkD2ifAaIDL5GKWUQIzVug0CycBfx9jZ6Qvs=; b=NuhhY1y9XNQJ5lUAU/ORdqRcI7BmgeqaSsgj1GsobCulyAXPXthqf+zJdcKPbesvJ+ 9a6j4Ge86QZMBIlCo+n8OprpWtZuJ7qrtFN3Dn5BZt36dOD6oJYZ9WQSM58BzkNZZvfM rLl4yxzQzi0Rb/D+u9MTLMUCsH+Su/MgceCzNb+7HTtc94P0DHVDTlPfAh7ftrcJHAPf OwhHVy3QC0I5HSjkpUR8eUXTYBwZfbMkpYoZ9VitdVlZZb7B4SVi+BWyPHR6sKtH5evL UMeQtTn56Gh3qynLp1deH25vQTvGyqwB5Y1pgy+Sc3EtFjJMIvilfLqaqbdnit/hwQMr HFnA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1704754130; x=1705358930; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZOnoZQfKkD2ifAaIDL5GKWUQIzVug0CycBfx9jZ6Qvs=; b=xBIAvw6/gDNa3apv4mOBqbUhEwm0WUVMXv0+pGZQGGM/wVFCm0Pw+8MT1Ph9yLEtP9 pMR7JjMJCxcN+dj2SFDQbUv+iTjF+ywUCo3us+cFj5SKB7L2mMfPHj/1RykGBD5+jXDf +6G7kOgDdGwlwsmXhn97ok/ADcXWVcAf4ULf25/wHt0/Cavw+SqS0+oUBY4t0BEDX/kk iibIYD8UQxyhxj1o2ANR8xP9KhVsRY+HaW3TOwQT1JxfglalqUEGO6csA41zeKfEDc+a RiBplEFYJGAVOb3cgit/wvdBDBbYWRkcC0dDwSznjBtF2upo70xTfhz8GLbZOG8wmmj/ dY7A== X-Gm-Message-State: AOJu0YxQqH3HhVYHYiz8YvaV68dk/5tpHjOPegcZNyInVXin5zjk/GLa ABDx1XQ9VF549JhxjcQYhKZ0FHXQubGTtQ== X-Google-Smtp-Source: AGHT+IGMbYkdfN1sAdx8/T8MqJNdwHUxqpbRB5tSltSYHKFVtpVizsQjTUOEj5gYeH4qWb9zfR5KsQ== X-Received: by 2002:a05:6e02:1d96:b0:35f:ff56:c0fd with SMTP id h22-20020a056e021d9600b0035fff56c0fdmr7642508ila.14.1704754129808; Mon, 08 Jan 2024 14:48:49 -0800 (PST) From: Taylor Simpson To: qemu-devel@nongnu.org Cc: bcain@quicinc.com, quic_mathbern@quicinc.com, sidneym@quicinc.com, quic_mliebel@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, ale@rev.ng, anjo@rev.ng, ltaylorsimpson@gmail.com Subject: [PATCH v2 1/3] Hexagon (target/hexagon) Use QEMU decodetree (32-bit instructions) Date: Mon, 8 Jan 2024 15:48:43 -0700 Message-Id: <20240108224845.285864-2-ltaylorsimpson@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240108224845.285864-1-ltaylorsimpson@gmail.com> References: <20240108224845.285864-1-ltaylorsimpson@gmail.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=2607:f8b0:4864:20::129; envelope-from=ltaylorsimpson@gmail.com; helo=mail-il1-x129.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, FREEMAIL_FROM=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1704754186484100001 The Decodetree Specification can be found here https://www.qemu.org/docs/master/devel/decodetree.html Covers all 32-bit instructions, including HVX We generate separate decoders for each instruction class. The reason will be more apparent in the next patch in this series. We add 2 new scripts gen_decodetree.py Generate the input to decodetree.py gen_trans_funcs.py Generate the trans_* functions used by the output of decodetree.py Since the functions generated by decodetree.py take DisasContext * as an argument, we add the argument to a couple of functions that didn't need it previously. We also set the insn field in DisasContext during decode because it is used by the trans_* functions. There is a g_assert_not_reached() in decode_insns() in decode.c to verify we never try to use the old decoder on 32-bit instructions Signed-off-by: Taylor Simpson --- target/hexagon/decode.h | 5 +- target/hexagon/decode.c | 54 ++++++++- target/hexagon/translate.c | 4 +- target/hexagon/README | 13 +- target/hexagon/gen_decodetree.py | 193 ++++++++++++++++++++++++++++++ target/hexagon/gen_trans_funcs.py | 132 ++++++++++++++++++++ target/hexagon/meson.build | 55 +++++++++ 7 files changed, 442 insertions(+), 14 deletions(-) create mode 100755 target/hexagon/gen_decodetree.py create mode 100755 target/hexagon/gen_trans_funcs.py diff --git a/target/hexagon/decode.h b/target/hexagon/decode.h index c66f5ea64d..3f3012b978 100644 --- a/target/hexagon/decode.h +++ b/target/hexagon/decode.h @@ -21,12 +21,13 @@ #include "cpu.h" #include "opcodes.h" #include "insn.h" +#include "translate.h" =20 void decode_init(void); =20 void decode_send_insn_to(Packet *packet, int start, int newloc); =20 -int decode_packet(int max_words, const uint32_t *words, Packet *pkt, - bool disas_only); +int decode_packet(DisasContext *ctx, int max_words, const uint32_t *words, + Packet *pkt, bool disas_only); =20 #endif diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c index 946c55cc71..bddad1f75e 100644 --- a/target/hexagon/decode.c +++ b/target/hexagon/decode.c @@ -52,6 +52,34 @@ DEF_REGMAP(R_8, 8, 0, 1, 2, 3, 4, 5, 6, 7) #define DECODE_MAPPED_REG(OPNUM, NAME) \ insn->regno[OPNUM] =3D DECODE_REGISTER_##NAME[insn->regno[OPNUM]]; =20 +/* Helper functions for decode_*_generated.c.inc */ +#define DECODE_MAPPED(NAME) \ +static int decode_mapped_reg_##NAME(DisasContext *ctx, int x) \ +{ \ + return DECODE_REGISTER_##NAME[x]; \ +} +DECODE_MAPPED(R_16) +DECODE_MAPPED(R_8) + +/* Helper function for decodetree_trans_funcs_generated.c.inc */ +static int shift_left(DisasContext *ctx, int x, int n, int immno) +{ + int ret =3D x; + Insn *insn =3D ctx->insn; + if (!insn->extension_valid || + insn->which_extended !=3D immno) { + ret <<=3D n; + } + return ret; +} + +/* Include the generated decoder for 32 bit insn */ +#include "decode_normal_generated.c.inc" +#include "decode_hvx_generated.c.inc" + +/* Include the generated helpers for the decoder */ +#include "decodetree_trans_funcs_generated.c.inc" + typedef struct { const struct DectreeTable *table_link; const struct DectreeTable *table_link_b; @@ -550,7 +578,8 @@ apply_extender(Packet *pkt, int i, uint32_t extender) int immed_num; uint32_t base_immed; =20 - immed_num =3D opcode_which_immediate_is_extended(pkt->insn[i].opcode); + immed_num =3D pkt->insn[i].which_extended; + g_assert(immed_num =3D=3D opcode_which_immediate_is_extended(pkt->insn= [i].opcode)); base_immed =3D pkt->insn[i].immed[immed_num]; =20 pkt->insn[i].immed[immed_num] =3D extender | fZXTN(6, 32, base_immed); @@ -762,12 +791,19 @@ decode_insns_tablewalk(Insn *insn, const DectreeTable= *table, } =20 static unsigned int -decode_insns(Insn *insn, uint32_t encoding) +decode_insns(DisasContext *ctx, Insn *insn, uint32_t encoding) { const DectreeTable *table; if (parse_bits(encoding) !=3D 0) { + if (decode_normal(ctx, encoding) || + decode_hvx(ctx, encoding)) { + insn->generate =3D opcode_genptr[insn->opcode]; + insn->iclass =3D iclass_bits(encoding); + return 1; + } /* Start with PP table - 32 bit instructions */ table =3D &dectree_table_DECODE_ROOT_32; + g_assert_not_reached(); } else { /* start with EE table - duplex instructions */ table =3D &dectree_table_DECODE_ROOT_EE; @@ -916,8 +952,8 @@ decode_set_slot_number(Packet *pkt) * or number of words used on success */ =20 -int decode_packet(int max_words, const uint32_t *words, Packet *pkt, - bool disas_only) +int decode_packet(DisasContext *ctx, int max_words, const uint32_t *words, + Packet *pkt, bool disas_only) { int num_insns =3D 0; int words_read =3D 0; @@ -930,9 +966,11 @@ int decode_packet(int max_words, const uint32_t *words= , Packet *pkt, memset(pkt, 0, sizeof(*pkt)); /* Try to build packet */ while (!end_of_packet && (words_read < max_words)) { + Insn *insn =3D &pkt->insn[num_insns]; + ctx->insn =3D insn; encoding32 =3D words[words_read]; end_of_packet =3D is_packet_end(encoding32); - new_insns =3D decode_insns(&pkt->insn[num_insns], encoding32); + new_insns =3D decode_insns(ctx, insn, encoding32); g_assert(new_insns > 0); /* * If we saw an extender, mark next word extended so immediate @@ -1006,9 +1044,13 @@ int decode_packet(int max_words, const uint32_t *wor= ds, Packet *pkt, int disassemble_hexagon(uint32_t *words, int nwords, bfd_vma pc, GString *buf) { + DisasContext ctx; Packet pkt; =20 - if (decode_packet(nwords, words, &pkt, true) > 0) { + memset(&ctx, 0, sizeof(DisasContext)); + ctx.pkt =3D &pkt; + + if (decode_packet(&ctx, nwords, words, &pkt, true) > 0) { snprint_a_pkt_disas(buf, &pkt, words, pc); return pkt.encod_pkt_size_in_bytes; } else { diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c index 666c061180..95579ae243 100644 --- a/target/hexagon/translate.c +++ b/target/hexagon/translate.c @@ -1033,10 +1033,10 @@ static void decode_and_translate_packet(CPUHexagonS= tate *env, DisasContext *ctx) return; } =20 - if (decode_packet(nwords, words, &pkt, false) > 0) { + ctx->pkt =3D &pkt; + if (decode_packet(ctx, nwords, words, &pkt, false) > 0) { pkt.pc =3D ctx->base.pc_next; HEX_DEBUG_PRINT_PKT(&pkt); - ctx->pkt =3D &pkt; gen_start_packet(ctx); for (i =3D 0; i < pkt.num_insns; i++) { ctx->insn =3D &pkt.insn[i]; diff --git a/target/hexagon/README b/target/hexagon/README index 69b2ffe9bb..1b2a4d0eac 100644 --- a/target/hexagon/README +++ b/target/hexagon/README @@ -189,11 +189,16 @@ the packet, and we mark the implicit writes. After t= he analysis is performed, we initialize the result register for each of the predicated assignments. =20 In addition to instruction semantics, we use a generator to create the dec= ode -tree. This generation is also a two step process. The first step is to r= un -target/hexagon/gen_dectree_import.c to produce +tree. This generation is a four step process. +Step 1 is to run target/hexagon/gen_dectree_import.c to produce /target/hexagon/iset.py -This file is imported by target/hexagon/dectree.py to produce - /target/hexagon/dectree_generated.h.inc +Step 2 is to import iset.py into target/hexagon/gen_decodetree.py to produ= ce + /target/hexagon/normal_decode_generated + /target/hexagon/hvx_decode_generated +Step 3 is to process the above files with QEMU's decodetree.py to produce + /target/hexagon/decode_*_generated.c.inc +Step 4 is to import iset.py into target/hexagon/gen_trans_funcs.py to prod= uce + /target/hexagon/decodetree_trans_funcs_generated.c.inc =20 *** Key Files *** =20 diff --git a/target/hexagon/gen_decodetree.py b/target/hexagon/gen_decodetr= ee.py new file mode 100755 index 0000000000..1693148ec0 --- /dev/null +++ b/target/hexagon/gen_decodetree.py @@ -0,0 +1,193 @@ +#!/usr/bin/env python3 + +## +## Copyright (c) 2024 Taylor Simpson +## +## 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 . +## + +import io +import re + +import sys +import textwrap +import iset +import hex_common + +encs =3D { + tag: "".join(reversed(iset.iset[tag]["enc"].replace(" ", ""))) + for tag in iset.tags + if iset.iset[tag]["enc"] !=3D "MISSING ENCODING" +} + + +regre =3D re.compile(r"((? 1: + raise Exception(f"{tag} has split register field!") + reg_enc_field =3D reg_enc_fields[0] + if 2 ** len(reg_enc_field) !=3D reg_num_choices: + raise Exception(f"{tag} has incorrect register field width= !") + + f.write(f"%{tag}_{reg_type}{reg_id}\t") + f.write(f"{enc.index(reg_enc_field)}:{len(reg_enc_field)}") + if (reg_type in num_registers and + reg_num_choices !=3D num_registers[reg_type]): + f.write(f"\t!function=3Ddecode_mapped_reg_{reg_mapping}") + f.write("\n") + regno +=3D 1 + + # Write the field definitions for the immediates + for imm in imms: + immno =3D 1 if imm[0].isupper() else 0 + imm_type =3D imm[0] + imm_width =3D int(imm[1]) + imm_letter =3D "i" if imm_type.islower() else "I" + fields =3D [] + sign_mark =3D "s" if imm_type.lower() in "sr" else "" + for m in reversed(list(re.finditer(imm_letter + "+", enc))): + fields.append(f"{m.start()}:{sign_mark}{m.end() - m.start(= )}") + sign_mark =3D "" + field_str =3D " ".join(fields) + f.write(f"%{tag}_{imm_type}{imm_letter}\t{field_str}\n") + + ## Handle instructions with unused encoding letters + ## Change the unused letters to ignored + if tag in tags_with_unused_d_encoding: + enc_str =3D enc_str.replace("d", "-") + if tag in tags_with_unused_t_encoding: + enc_str =3D enc_str.replace("t", "-") + + # Replace the operand letters with . + for x in operand_letters: + enc_str =3D enc_str.replace(x, ".") + + # Write the instruction format + f.write(f"@{tag}\t{enc_str}") + for reg in regs: + reg_type =3D reg[0] + reg_id =3D reg[1] + f.write(f" {reg_type}{reg_id}=3D%{tag}_{reg_type}{reg_id}") + for imm in imms: + imm_type =3D imm[0] + imm_letter =3D "i" if imm_type.islower() else "I" + f.write(f" {imm_type}{imm_letter}=3D%{tag}_{imm_type}{imm_lett= er}") + + f.write(" %PP\n") + + # Replace the 0s and 1s with . + for x in { "0", "1" }: + enc_str =3D enc_str.replace(x, ".") + + # Write the instruction pattern + f.write(f"{tag}\t{enc_str} @{tag}\n") + + +if __name__ =3D=3D "__main__": + hex_common.read_semantics_file(sys.argv[1]) + class_to_decode =3D sys.argv[2] + with open(sys.argv[3], "w") as f: + gen_decodetree_file(f, class_to_decode) diff --git a/target/hexagon/gen_trans_funcs.py b/target/hexagon/gen_trans_f= uncs.py new file mode 100755 index 0000000000..c907131009 --- /dev/null +++ b/target/hexagon/gen_trans_funcs.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python3 + +## +## Copyright (c) 2024 Taylor Simpson +## +## 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 . +## + +import io +import re + +import sys +import textwrap +import iset +import hex_common + +encs =3D { + tag: "".join(reversed(iset.iset[tag]["enc"].replace(" ", ""))) + for tag in iset.tags + if iset.iset[tag]["enc"] !=3D "MISSING ENCODING" +} + + +regre =3D re.compile(r"((?which_extended =3D {0 if letter.islower() else 1}; + """)) + +## +## Generate the QEMU decodetree trans_ function for each instruction +## For A2_add: Rd32=3Dadd(Rs32,Rt32) +## We produce: +## static bool trans_A2_add(DisasContext *ctx, arg_A2_add *args) +## { +## Insn *insn =3D ctx->insn; +## insn->opcode =3D A2_add; +## insn->regno[0] =3D args->Rd; +## insn->regno[1] =3D args->Rs; +## insn->regno[2] =3D args->Rt; +## return true; +## } +## +def gen_trans_funcs(f, classes): + f.write(f"/* DO NOT MODIFY - This file is generated by {sys.argv[0]} *= /\n\n") + for tag in sorted(encs.keys(), key=3Diset.tags.index): + if skip_tag(tag, classes): + continue + + regs =3D ordered_unique(regre.findall(iset.iset[tag]["syntax"])) + imms =3D ordered_unique(immre.findall(iset.iset[tag]["syntax"])) + + f.write(textwrap.dedent(f"""\ + static bool trans_{tag}(DisasContext *ctx, arg_{tag} *args) + {open_curly} + Insn *insn =3D ctx->insn; + insn->opcode =3D {tag}; + """)) + + regno =3D 0 + for reg in regs: + reg_type =3D reg[0] + reg_id =3D reg[1] + f.write(code_fmt(f"""\ + insn->regno[{regno}] =3D args->{reg_type}{reg_id}; + """)) + regno +=3D 1 + + if len(imms) !=3D 0: + mark_which_imm_extended(f, tag) + + for imm in imms: + imm_type =3D imm[0] + imm_letter =3D "i" if imm_type.islower() else "I" + immno =3D 0 if imm_type.islower() else 1 + imm_shift =3D int(imm[2]) if imm[2] else 0 + if imm_shift: + f.write(code_fmt(f"""\ + insn->immed[{immno}] =3D + shift_left(ctx, args->{imm_type}{imm_letter}, + {imm_shift}, {immno}); + """)) + else: + f.write(code_fmt(f"""\ + insn->immed[{immno}] =3D args->{imm_type}{imm_letter}; + """)) + + f.write(textwrap.dedent(f"""\ + return true; + {close_curly} + """)) + + +if __name__ =3D=3D "__main__": + hex_common.read_semantics_file(sys.argv[1]) + with open(sys.argv[2], "w") as f: + gen_trans_funcs(f, { "NORMAL", "EXT_mmvec" }) diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build index da8e608d00..831bd5716a 100644 --- a/target/hexagon/meson.build +++ b/target/hexagon/meson.build @@ -133,6 +133,61 @@ dectree_generated =3D custom_target( ) hexagon_ss.add(dectree_generated) =20 +# +# Generate the input to the QEMU decodetree.py script +# +normal_decode_generated =3D custom_target( + 'normal_decode_generated', + output: 'normal_decode_generated', + depends: [iset_py, semantics_generated], + env: {'PYTHONPATH': meson.current_build_dir()}, + command: [python, files('gen_decodetree.py'), semantics_generated, 'NO= RMAL', '@OUTPUT@'], +) +hexagon_ss.add(normal_decode_generated) + +hvx_decode_generated =3D custom_target( + 'hvx_decode_generated', + output: 'hvx_decode_generated', + depends: [iset_py, semantics_generated], + env: {'PYTHONPATH': meson.current_build_dir()}, + command: [python, files('gen_decodetree.py'), semantics_generated, 'EX= T_mmvec', '@OUTPUT@'], +) +hexagon_ss.add(hvx_decode_generated) + +# +# Run the QEMU decodetree.py script to produce the instruction decoder +# +decodetree_py =3D meson.current_source_dir() / '../../scripts/decodetree.p= y' +decode_normal_generated =3D custom_target( + 'decode_normal_generated.c.inc', + output: 'decode_normal_generated.c.inc', + input: normal_decode_generated, + env: {'PYTHONPATH': meson.current_build_dir()}, + command: [python, files(decodetree_py), normal_decode_generated, '--st= atic-decode=3Ddecode_normal', '-o', '@OUTPUT@'], +) +hexagon_ss.add(decode_normal_generated) + +decode_hvx_generated =3D custom_target( + 'decode_hvx_generated.c.inc', + output: 'decode_hvx_generated.c.inc', + input: hvx_decode_generated, + env: {'PYTHONPATH': meson.current_build_dir()}, + command: [python, files(decodetree_py), hvx_decode_generated, '--stati= c-decode=3Ddecode_hvx', '-o', '@OUTPUT@'], +) +hexagon_ss.add(decode_hvx_generated) + +# +# Generate the trans_* functions that the decoder will use +# +decodetree_trans_funcs_generated =3D custom_target( + 'decodetree_trans_funcs_generated.c.inc', + output: 'decodetree_trans_funcs_generated.c.inc', + depends: [iset_py, semantics_generated], + env: {'PYTHONPATH': meson.current_build_dir()}, + command: [python, files('gen_trans_funcs.py'), semantics_generated, '@= OUTPUT@'], +) +hexagon_ss.add(decodetree_trans_funcs_generated) + hexagon_ss.add(files( 'cpu.c', 'translate.c', --=20 2.34.1 From nobody Tue Nov 26 20:36:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1704754157; cv=none; d=zohomail.com; s=zohoarc; b=kXqxthgptSo0EiRQ0hXXaMRMsStq2TOul/fcNpImXjuTOzL+CsEnfLXkVA24MWRVi5BS/vtWS27t/xXRU9FIR5gCx6fXy4XIhUeVejrQEmcs6GVgKJDb7W8PHqUfVOAgCeAmvvlhETvO+yw2reGlUS123sRnshEFCqyLDhzxcds= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1704754157; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=LD0J90wvo9OOp0y/+eqEnhanYAzvneHwaomHEfxgwnc=; b=NcQ1rfK/rpSEF2ijilgD1I3LezGK62OYOcLDL1iPbqQKJHAyEwEUHiFMcdpLsTF9FmFpmscK6WCfHrWj6n7CFofAXL3/JiXgsqCW8hUfb/VITuRDlOTCJSL8hLwBUIAkTCL0SN/zAXMTqE2i05UhaX3UpWIr8jTRkgYJB61BjoI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1704754157956643.2368564166808; Mon, 8 Jan 2024 14:49:17 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rMyQT-0006Wy-Ic; Mon, 08 Jan 2024 17:48:57 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rMyQR-0006WI-BU for qemu-devel@nongnu.org; Mon, 08 Jan 2024 17:48:55 -0500 Received: from mail-io1-xd35.google.com ([2607:f8b0:4864:20::d35]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rMyQP-0008VQ-1u for qemu-devel@nongnu.org; Mon, 08 Jan 2024 17:48:55 -0500 Received: by mail-io1-xd35.google.com with SMTP id ca18e2360f4ac-7bbec1d1c9dso147465239f.1 for ; Mon, 08 Jan 2024 14:48:52 -0800 (PST) Received: from taylor-ubuntu.hsd1.co.comcast.net (c-73-169-12-54.hsd1.co.comcast.net. [73.169.12.54]) by smtp.gmail.com with ESMTPSA id t7-20020a056638204700b0046e08e513b2sm241877jaj.116.2024.01.08.14.48.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Jan 2024 14:48:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1704754131; x=1705358931; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=LD0J90wvo9OOp0y/+eqEnhanYAzvneHwaomHEfxgwnc=; b=E7gQiZaAidvUmCKA/lQJ5wBW+KE7LXk9VGaaJgdAkNqGKyC/b9qQeFgV1WzzME5w5t i2ZaUvMnWeFOyS/nsq6GWFGkKgpRc7qaq98Aue59FZNL/pndhnthslKqXny6W18/fpPJ pim7gGaPEFfJZKjJW0nRI8QtQSvTuYDroEayCQQPrSjwQxQAlkYg5c5JUOLzTkqQ8m3P DVpliqfKtYELAwr/F55uh2ktt6gloVN76DGntqBybQreX5IiinHbT+4soydj02tFJMDC ZRSs4a5/eyiJphTv8DyBvlaIb+wY21ytx2rP6Oks/u3ywt9WAXSYj63dP78gweX14DZO CZmw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1704754131; x=1705358931; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=LD0J90wvo9OOp0y/+eqEnhanYAzvneHwaomHEfxgwnc=; b=c0H4H4wSuqm6WH/ubHLwH43tlWGP7kN2d0q0lHOalndLEFAOVEEJsqEmRjzOUmWLe/ pNyeNNiPtBISB2IS3Vtsl7EGoC8G83+6rKyUBYcblngvo6Lf9J9W70Gx4bnUB/WiXxPp BBqIVYEid1MC7QIUbpjy6hn637vZ5TSIO4DZhozqbVsvqLOp5SSPf6X2S9UwKYsppdPg UyMEGBu+1Apqvr/fAxmIjTBQnV+MS3HdSBtz/yV6oC5yX5CjQim+fuuej3Oo8XDkWfBg pgpeeEVIiMrr5gaOor4YT5n2ef8bS6PUu6/82GQOuZe/Y5pVthdoAEgMIgNvL49pTigM hCrQ== X-Gm-Message-State: AOJu0Yz11WT7vb2CVAQLymOQfWUIzXZbCMknDdp/kreiRvGomKnjdA9M j8Wostj0rjK+eHp1FnUMuQmetUoKvknwzw== X-Google-Smtp-Source: AGHT+IE0r530paTaefmXeK4JGMp5Z5+3tpnUW0SlFmR6gXLY2Mkw6/ZmFLypS12hRupZQlLG847nfw== X-Received: by 2002:a5e:dd07:0:b0:7b7:fac7:fda8 with SMTP id t7-20020a5edd07000000b007b7fac7fda8mr6273092iop.39.1704754131258; Mon, 08 Jan 2024 14:48:51 -0800 (PST) From: Taylor Simpson To: qemu-devel@nongnu.org Cc: bcain@quicinc.com, quic_mathbern@quicinc.com, sidneym@quicinc.com, quic_mliebel@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, ale@rev.ng, anjo@rev.ng, ltaylorsimpson@gmail.com Subject: [PATCH v2 2/3] Hexagon (target/hexagon) Use QEMU decodetree (16-bit instructions) Date: Mon, 8 Jan 2024 15:48:44 -0700 Message-Id: <20240108224845.285864-3-ltaylorsimpson@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240108224845.285864-1-ltaylorsimpson@gmail.com> References: <20240108224845.285864-1-ltaylorsimpson@gmail.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=2607:f8b0:4864:20::d35; envelope-from=ltaylorsimpson@gmail.com; helo=mail-io1-xd35.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, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1704754158406100001 Section 10.3 of the Hexagon V73 Programmer's Reference Manual A duplex is encoded as a 32-bit instruction with bits [15:14] set to 00. The sub-instructions that comprise a duplex are encoded as 13-bit fields in the duplex. Create a decoder for each subinstruction class (a, l1, l2, s1, s2). Extend gen_trans_funcs.py to handle all instructions rather than filter by instruction class. There is a g_assert_not_reached() in decode_insns() in decode.c to verify we never try to use the old decoder on 16-bit instructions. Signed-off-by: Taylor Simpson Reviewed-by: Brian Cain --- target/hexagon/decode.c | 85 +++++++++++++++++++++++++++++ target/hexagon/README | 1 + target/hexagon/gen_decodetree.py | 14 ++++- target/hexagon/gen_trans_funcs.py | 12 +---- target/hexagon/meson.build | 90 +++++++++++++++++++++++++++++++ 5 files changed, 190 insertions(+), 12 deletions(-) diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c index bddad1f75e..160b23a895 100644 --- a/target/hexagon/decode.c +++ b/target/hexagon/decode.c @@ -60,6 +60,7 @@ static int decode_mapped_reg_##NAME(DisasContext *ctx, in= t x) \ } DECODE_MAPPED(R_16) DECODE_MAPPED(R_8) +DECODE_MAPPED(R__8) =20 /* Helper function for decodetree_trans_funcs_generated.c.inc */ static int shift_left(DisasContext *ctx, int x, int n, int immno) @@ -77,6 +78,13 @@ static int shift_left(DisasContext *ctx, int x, int n, i= nt immno) #include "decode_normal_generated.c.inc" #include "decode_hvx_generated.c.inc" =20 +/* Include the generated decoder for 16 bit insn */ +#include "decode_subinsn_a_generated.c.inc" +#include "decode_subinsn_l1_generated.c.inc" +#include "decode_subinsn_l2_generated.c.inc" +#include "decode_subinsn_s1_generated.c.inc" +#include "decode_subinsn_s2_generated.c.inc" + /* Include the generated helpers for the decoder */ #include "decodetree_trans_funcs_generated.c.inc" =20 @@ -790,6 +798,63 @@ decode_insns_tablewalk(Insn *insn, const DectreeTable = *table, } } =20 +/* + * Section 10.3 of the Hexagon V73 Programmer's Reference Manual + * + * A duplex is encoded as a 32-bit instruction with bits [15:14] set to 00. + * The sub-instructions that comprise a duplex are encoded as 13-bit fields + * in the duplex. + * + * Per table 10-4, the 4-bit duplex iclass is encoded in bits 31:29, 13 + */ +static uint32_t get_duplex_iclass(uint32_t encoding) +{ + uint32_t iclass =3D extract32(encoding, 13, 1); + iclass =3D deposit32(iclass, 1, 3, extract32(encoding, 29, 3)); + return iclass; +} + +/* + * Per table 10-5, the duplex ICLASS field values that specify the group of + * each sub-instruction in a duplex + * + * This table points to the decode instruction for each entry in the table + */ +typedef bool (*subinsn_decode_func)(DisasContext *ctx, uint16_t insn); +typedef struct { + subinsn_decode_func decode_slot0_subinsn; + subinsn_decode_func decode_slot1_subinsn; +} subinsn_decode_groups; + +static const subinsn_decode_groups decode_groups[16] =3D { + [0x0] =3D { decode_subinsn_l1, decode_subinsn_l1 }, + [0x1] =3D { decode_subinsn_l2, decode_subinsn_l1 }, + [0x2] =3D { decode_subinsn_l2, decode_subinsn_l2 }, + [0x3] =3D { decode_subinsn_a, decode_subinsn_a }, + [0x4] =3D { decode_subinsn_l1, decode_subinsn_a }, + [0x5] =3D { decode_subinsn_l2, decode_subinsn_a }, + [0x6] =3D { decode_subinsn_s1, decode_subinsn_a }, + [0x7] =3D { decode_subinsn_s2, decode_subinsn_a }, + [0x8] =3D { decode_subinsn_s1, decode_subinsn_l1 }, + [0x9] =3D { decode_subinsn_s1, decode_subinsn_l2 }, + [0xa] =3D { decode_subinsn_s1, decode_subinsn_s1 }, + [0xb] =3D { decode_subinsn_s2, decode_subinsn_s1 }, + [0xc] =3D { decode_subinsn_s2, decode_subinsn_l1 }, + [0xd] =3D { decode_subinsn_s2, decode_subinsn_l2 }, + [0xe] =3D { decode_subinsn_s2, decode_subinsn_s2 }, + [0xf] =3D { NULL, NULL }, /* Reserved */ +}; + +static uint16_t get_slot0_subinsn(uint32_t encoding) +{ + return extract32(encoding, 0, 13); +} + +static uint16_t get_slot1_subinsn(uint32_t encoding) +{ + return extract32(encoding, 16, 13); +} + static unsigned int decode_insns(DisasContext *ctx, Insn *insn, uint32_t encoding) { @@ -805,8 +870,28 @@ decode_insns(DisasContext *ctx, Insn *insn, uint32_t e= ncoding) table =3D &dectree_table_DECODE_ROOT_32; g_assert_not_reached(); } else { + uint32_t iclass =3D get_duplex_iclass(encoding); + unsigned int slot0_subinsn =3D get_slot0_subinsn(encoding); + unsigned int slot1_subinsn =3D get_slot1_subinsn(encoding); + subinsn_decode_func decode_slot0_subinsn =3D + decode_groups[iclass].decode_slot0_subinsn; + subinsn_decode_func decode_slot1_subinsn =3D + decode_groups[iclass].decode_slot1_subinsn; + + /* The slot1 subinsn needs to be in the packet first */ + if (decode_slot1_subinsn(ctx, slot1_subinsn)) { + insn->generate =3D opcode_genptr[insn->opcode]; + insn->iclass =3D iclass_bits(encoding); + ctx->insn =3D ++insn; + if (decode_slot0_subinsn(ctx, slot0_subinsn)) { + insn->generate =3D opcode_genptr[insn->opcode]; + insn->iclass =3D iclass_bits(encoding); + return 2; + } + } /* start with EE table - duplex instructions */ table =3D &dectree_table_DECODE_ROOT_EE; + g_assert_not_reached(); } return decode_insns_tablewalk(insn, table, encoding); } diff --git a/target/hexagon/README b/target/hexagon/README index 1b2a4d0eac..746ebec378 100644 --- a/target/hexagon/README +++ b/target/hexagon/README @@ -195,6 +195,7 @@ Step 1 is to run target/hexagon/gen_dectree_import.c to= produce Step 2 is to import iset.py into target/hexagon/gen_decodetree.py to produ= ce /target/hexagon/normal_decode_generated /target/hexagon/hvx_decode_generated + /target/hexagon/subinsn_*_decode_generated Step 3 is to process the above files with QEMU's decodetree.py to produce /target/hexagon/decode_*_generated.c.inc Step 4 is to import iset.py into target/hexagon/gen_trans_funcs.py to prod= uce diff --git a/target/hexagon/gen_decodetree.py b/target/hexagon/gen_decodetr= ee.py index 1693148ec0..2dff975f55 100755 --- a/target/hexagon/gen_decodetree.py +++ b/target/hexagon/gen_decodetree.py @@ -96,8 +96,10 @@ def skip_tag(tag, class_to_decode): ## A2_add ..................-.....---..... @A2_add ## def gen_decodetree_file(f, class_to_decode): + is_subinsn =3D class_to_decode.startswith("SUBINSN_") f.write(f"## DO NOT MODIFY - This file is generated by {sys.argv[0]}\n= \n") - f.write("%PP\t14:2\n\n") + if not is_subinsn: + f.write("%PP\t14:2\n\n") for tag in sorted(encs.keys(), key=3Diset.tags.index): if skip_tag(tag, class_to_decode): continue @@ -107,6 +109,12 @@ def gen_decodetree_file(f, class_to_decode): =20 enc =3D encs[tag] enc_str =3D "".join(reversed(encs[tag])) + + # The subinstructions come with a 13-bit encoding, but + # decodetree.py needs 16 bits + if is_subinsn: + enc_str =3D "---" + enc_str + f.write(f"## {tag}:\t{enc_str}\n") f.write("##\n") =20 @@ -176,7 +184,9 @@ def gen_decodetree_file(f, class_to_decode): imm_letter =3D "i" if imm_type.islower() else "I" f.write(f" {imm_type}{imm_letter}=3D%{tag}_{imm_type}{imm_lett= er}") =20 - f.write(" %PP\n") + if not is_subinsn: + f.write(" %PP") + f.write("\n") =20 # Replace the 0s and 1s with . for x in { "0", "1" }: diff --git a/target/hexagon/gen_trans_funcs.py b/target/hexagon/gen_trans_f= uncs.py index c907131009..53e844a44b 100755 --- a/target/hexagon/gen_trans_funcs.py +++ b/target/hexagon/gen_trans_funcs.py @@ -40,11 +40,6 @@ def ordered_unique(l): return sorted(set(l), key=3Dl.index) =20 =20 -def skip_tag(tag, classes): - enc_class =3D iset.iset[tag]["enc_class"] - return enc_class not in classes - - def code_fmt(txt): return textwrap.indent(textwrap.dedent(txt), " ") =20 @@ -76,12 +71,9 @@ def mark_which_imm_extended(f, tag): ## return true; ## } ## -def gen_trans_funcs(f, classes): +def gen_trans_funcs(f): f.write(f"/* DO NOT MODIFY - This file is generated by {sys.argv[0]} *= /\n\n") for tag in sorted(encs.keys(), key=3Diset.tags.index): - if skip_tag(tag, classes): - continue - regs =3D ordered_unique(regre.findall(iset.iset[tag]["syntax"])) imms =3D ordered_unique(immre.findall(iset.iset[tag]["syntax"])) =20 @@ -129,4 +121,4 @@ def gen_trans_funcs(f, classes): if __name__ =3D=3D "__main__": hex_common.read_semantics_file(sys.argv[1]) with open(sys.argv[2], "w") as f: - gen_trans_funcs(f, { "NORMAL", "EXT_mmvec" }) + gen_trans_funcs(f) diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build index 831bd5716a..1bd1ebcba1 100644 --- a/target/hexagon/meson.build +++ b/target/hexagon/meson.build @@ -154,6 +154,51 @@ hvx_decode_generated =3D custom_target( ) hexagon_ss.add(hvx_decode_generated) =20 +subinsn_a_decode_generated =3D custom_target( + 'subinsn_a_decode_generated', + output: 'subinsn_a_decode_generated', + depends: [iset_py, semantics_generated], + env: {'PYTHONPATH': meson.current_build_dir()}, + command: [python, files('gen_decodetree.py'), semantics_generated, 'SU= BINSN_A', '@OUTPUT@'], +) +hexagon_ss.add(subinsn_a_decode_generated) + +subinsn_l1_decode_generated =3D custom_target( + 'subinsn_l1_decode_generated', + output: 'subinsn_l1_decode_generated', + depends: [iset_py, semantics_generated], + env: {'PYTHONPATH': meson.current_build_dir()}, + command: [python, files('gen_decodetree.py'), semantics_generated, 'SU= BINSN_L1', '@OUTPUT@'], +) +hexagon_ss.add(subinsn_l1_decode_generated) + +subinsn_l2_decode_generated =3D custom_target( + 'subinsn_l2_decode_generated', + output: 'subinsn_l2_decode_generated', + depends: [iset_py, semantics_generated], + env: {'PYTHONPATH': meson.current_build_dir()}, + command: [python, files('gen_decodetree.py'), semantics_generated, 'SU= BINSN_L2', '@OUTPUT@'], +) +hexagon_ss.add(subinsn_l2_decode_generated) + +subinsn_s1_decode_generated =3D custom_target( + 'subinsn_s1_decode_generated', + output: 'subinsn_s1_decode_generated', + depends: [iset_py, semantics_generated], + env: {'PYTHONPATH': meson.current_build_dir()}, + command: [python, files('gen_decodetree.py'), semantics_generated, 'SU= BINSN_S1', '@OUTPUT@'], +) +hexagon_ss.add(subinsn_s1_decode_generated) + +subinsn_s2_decode_generated =3D custom_target( + 'subinsn_s2_decode_generated', + output: 'subinsn_s2_decode_generated', + depends: [iset_py, semantics_generated], + env: {'PYTHONPATH': meson.current_build_dir()}, + command: [python, files('gen_decodetree.py'), semantics_generated, 'SU= BINSN_S2', '@OUTPUT@'], +) +hexagon_ss.add(subinsn_s2_decode_generated) + # # Run the QEMU decodetree.py script to produce the instruction decoder # @@ -176,6 +221,51 @@ decode_hvx_generated =3D custom_target( ) hexagon_ss.add(decode_hvx_generated) =20 +decode_subinsn_a_generated =3D custom_target( + 'decode_subinsn_a_generated.c.inc', + output: 'decode_subinsn_a_generated.c.inc', + input: subinsn_a_decode_generated, + env: {'PYTHONPATH': meson.current_build_dir()}, + command: [python, files(decodetree_py), subinsn_a_decode_generated, ['= --static-decode=3Ddecode_subinsn_a', '--insnwidth=3D16'], '-o', '@OUTPUT@'], +) +hexagon_ss.add(decode_subinsn_a_generated) + +decode_subinsn_l1_generated =3D custom_target( + 'decode_subinsn_l1_generated.c.inc', + output: 'decode_subinsn_l1_generated.c.inc', + input: subinsn_l1_decode_generated, + env: {'PYTHONPATH': meson.current_build_dir()}, + command: [python, files(decodetree_py), subinsn_l1_decode_generated, [= '--static-decode=3Ddecode_subinsn_l1', '--insnwidth=3D16'], '-o', '@OUTPUT@= '], +) +hexagon_ss.add(decode_subinsn_l1_generated) + +decode_subinsn_l2_generated =3D custom_target( + 'decode_subinsn_l2_generated.c.inc', + output: 'decode_subinsn_l2_generated.c.inc', + input: subinsn_l2_decode_generated, + env: {'PYTHONPATH': meson.current_build_dir()}, + command: [python, files(decodetree_py), subinsn_l2_decode_generated, [= '--static-decode=3Ddecode_subinsn_l2', '--insnwidth=3D16'], '-o', '@OUTPUT@= '], +) +hexagon_ss.add(decode_subinsn_l2_generated) + +decode_subinsn_s1_generated =3D custom_target( + 'decode_subinsn_s1_generated.c.inc', + output: 'decode_subinsn_s1_generated.c.inc', + input: subinsn_s1_decode_generated, + env: {'PYTHONPATH': meson.current_build_dir()}, + command: [python, files(decodetree_py), subinsn_s1_decode_generated, [= '--static-decode=3Ddecode_subinsn_s1', '--insnwidth=3D16'], '-o', '@OUTPUT@= '], +) +hexagon_ss.add(decode_subinsn_s1_generated) + +decode_subinsn_s2_generated =3D custom_target( + 'decode_subinsn_s2_generated.c.inc', + output: 'decode_subinsn_s2_generated.c.inc', + input: subinsn_s2_decode_generated, + env: {'PYTHONPATH': meson.current_build_dir()}, + command: [python, files(decodetree_py), subinsn_s2_decode_generated, [= '--static-decode=3Ddecode_subinsn_s2', '--insnwidth=3D16'], '-o', '@OUTPUT@= '], +) +hexagon_ss.add(decode_subinsn_s2_generated) + # # Generate the trans_* functions that the decoder will use # --=20 2.34.1 From nobody Tue Nov 26 20:36:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1704754174; cv=none; d=zohomail.com; s=zohoarc; b=Busu0wdxqjnYlVnMf7IZtwicg8WOEjbb6VN471rxtcxUdrm1jdlqA2+F0dGT5g42lYj8kW9pHkH+Wv7FvQ7BhZxchnokzv3cvB7Kc9ZipqWcnJKsmf63kLVfScovQEss0vsOSMTZueUgwx5nNcCxl9FsNw0bMIU9cZeVe3i1IP4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1704754174; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=8WXx1KgQGvaoHAN3dxMBX85FHZrbmTm10LepTlf7fW8=; b=g4h5k/PtNrmjbR06Fbb5Zk/6x/288vb6or4bNUCoAo6bU3dkRMpq3I4mYxbqfkHR7qL4JQV0fMXmmOk3rjR3rnAtVj9vjCa0wFy1v2GF8XMYHlp4q2fnfWpiP1/nUMQTOEzlY+LFGLE88YJ0GmWkqWmSlrh7FL6yUttyFo9HBOQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 17047541747441012.1714140207081; Mon, 8 Jan 2024 14:49:34 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rMyQY-0006be-5O; Mon, 08 Jan 2024 17:49:02 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rMyQV-0006XF-Tq for qemu-devel@nongnu.org; Mon, 08 Jan 2024 17:48:59 -0500 Received: from mail-io1-xd29.google.com ([2607:f8b0:4864:20::d29]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rMyQS-0008W2-E5 for qemu-devel@nongnu.org; Mon, 08 Jan 2024 17:48:59 -0500 Received: by mail-io1-xd29.google.com with SMTP id ca18e2360f4ac-7bed944f553so4404339f.3 for ; Mon, 08 Jan 2024 14:48:56 -0800 (PST) Received: from taylor-ubuntu.hsd1.co.comcast.net (c-73-169-12-54.hsd1.co.comcast.net. [73.169.12.54]) by smtp.gmail.com with ESMTPSA id t7-20020a056638204700b0046e08e513b2sm241877jaj.116.2024.01.08.14.48.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Jan 2024 14:48:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1704754135; x=1705358935; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=8WXx1KgQGvaoHAN3dxMBX85FHZrbmTm10LepTlf7fW8=; b=SblaAGl8JPTo2U7zWqV5CPH3dd34n+3OkntWNcqiKGU4BqGm9cOQoA5CrLjc4VZ35m WDy4oqv1DNHZe+sipnX+GLyAfR9v039DfdCYukZabdUeJMzkWTiw3l5EvPr6OJ0Sufc8 1YY86KhDMgkVz9AUIk3sNuVcjzH8EtTQL2LMhGp8uuKilp/PxW2/p0laBvMgCt0zI0aD FNZRWohlabtyCiZSJ/umlEaQbnFUojbegr+1oGx2NtyGbjNhqA+dQ0xr6f44GEpn39/Z JJYWpoEe9vqG1fMQcoPRxyWwj/dvDvB5kIjvQ2UE20DWP382dxjqW5VkWS1GgqQldsvl iWWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1704754135; x=1705358935; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=8WXx1KgQGvaoHAN3dxMBX85FHZrbmTm10LepTlf7fW8=; b=rCauYLh7PAd8IWBE7Xwaw3JhvYJFI1D3m0QuTpmbHTcmYCL1TflZ1i5BmHyBNdflTa 0Q+k6BkpCYCmoVHsHusruNdhU6jr3Ykec9tHzFwXC7r6i4QfhZLC6sdYbW582MAD9SrS s0QYyPKxMLcLYsPGY+qlXJJ6w6zflaT4qmevZ+F7pPbJz+UeetGmikbu5n2FHXCkaexp PFo1k0YBwBGCurMjsTfE78JgZxgM46SjhSMVvOIiar2dfbwclV54sv2hBRvO03KN+clq t110zJX+z0yxwvKUhhkigb9kKPNdakk8XvYOLHZUOJHlcjUGrmos+AwU/3lF4ex/Bcb5 NZYw== X-Gm-Message-State: AOJu0Yy1IPq37AghLQwQFmO0u88IjFmZzjPymZzPEIrC/baBZJx5NubR iVxoD2lva2D5KmkLxfXlFAoZsd4iV5mijQ== X-Google-Smtp-Source: AGHT+IFhYxNQQ6GE7XCa/UZYYTag4MjoDWQFMMNVjJuU5zSTGTXSwwwaxKyQW6V+9JTK4Z/YKklf6g== X-Received: by 2002:a6b:e70c:0:b0:7ba:b744:bb0 with SMTP id b12-20020a6be70c000000b007bab7440bb0mr5912602ioh.35.1704754132663; Mon, 08 Jan 2024 14:48:52 -0800 (PST) From: Taylor Simpson To: qemu-devel@nongnu.org Cc: bcain@quicinc.com, quic_mathbern@quicinc.com, sidneym@quicinc.com, quic_mliebel@quicinc.com, richard.henderson@linaro.org, philmd@linaro.org, ale@rev.ng, anjo@rev.ng, ltaylorsimpson@gmail.com Subject: [PATCH v2 3/3] Hexagon (target/hexagon) Remove old dectree.py Date: Mon, 8 Jan 2024 15:48:45 -0700 Message-Id: <20240108224845.285864-4-ltaylorsimpson@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240108224845.285864-1-ltaylorsimpson@gmail.com> References: <20240108224845.285864-1-ltaylorsimpson@gmail.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=2607:f8b0:4864:20::d29; envelope-from=ltaylorsimpson@gmail.com; helo=mail-io1-xd29.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, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1704754176493100003 Now that we are using QEMU decodetree.py, remove the old decoder Signed-off-by: Taylor Simpson Reviewed-by: Brian Cain --- target/hexagon/opcodes.h | 2 - target/hexagon/decode.c | 344 ------------------------ target/hexagon/gen_dectree_import.c | 49 ---- target/hexagon/opcodes.c | 29 -- target/hexagon/dectree.py | 403 ---------------------------- target/hexagon/meson.build | 12 - 6 files changed, 839 deletions(-) delete mode 100755 target/hexagon/dectree.py diff --git a/target/hexagon/opcodes.h b/target/hexagon/opcodes.h index 6e90e00fe2..fa7e321950 100644 --- a/target/hexagon/opcodes.h +++ b/target/hexagon/opcodes.h @@ -53,6 +53,4 @@ extern const OpcodeEncoding opcode_encodings[XX_LAST_OPCO= DE]; =20 void opcode_init(void); =20 -int opcode_which_immediate_is_extended(Opcode opcode); - #endif diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c index 160b23a895..a40210ca1e 100644 --- a/target/hexagon/decode.c +++ b/target/hexagon/decode.c @@ -88,175 +88,6 @@ static int shift_left(DisasContext *ctx, int x, int n, = int immno) /* Include the generated helpers for the decoder */ #include "decodetree_trans_funcs_generated.c.inc" =20 -typedef struct { - const struct DectreeTable *table_link; - const struct DectreeTable *table_link_b; - Opcode opcode; - enum { - DECTREE_ENTRY_INVALID, - DECTREE_TABLE_LINK, - DECTREE_SUBINSNS, - DECTREE_EXTSPACE, - DECTREE_TERMINAL - } type; -} DectreeEntry; - -typedef struct DectreeTable { - unsigned int (*lookup_function)(int startbit, int width, uint32_t opco= de); - unsigned int size; - unsigned int startbit; - unsigned int width; - const DectreeEntry table[]; -} DectreeTable; - -#define DECODE_NEW_TABLE(TAG, SIZE, WHATNOT) \ - static const DectreeTable dectree_table_##TAG; -#define TABLE_LINK(TABLE) /* NOTHING */ -#define TERMINAL(TAG, ENC) /* NOTHING */ -#define SUBINSNS(TAG, CLASSA, CLASSB, ENC) /* NOTHING */ -#define EXTSPACE(TAG, ENC) /* NOTHING */ -#define INVALID() /* NOTHING */ -#define DECODE_END_TABLE(...) /* NOTHING */ -#define DECODE_MATCH_INFO(...) /* NOTHING */ -#define DECODE_LEGACY_MATCH_INFO(...) /* NOTHING */ -#define DECODE_OPINFO(...) /* NOTHING */ - -#include "dectree_generated.h.inc" - -#undef DECODE_OPINFO -#undef DECODE_MATCH_INFO -#undef DECODE_LEGACY_MATCH_INFO -#undef DECODE_END_TABLE -#undef INVALID -#undef TERMINAL -#undef SUBINSNS -#undef EXTSPACE -#undef TABLE_LINK -#undef DECODE_NEW_TABLE -#undef DECODE_SEPARATOR_BITS - -#define DECODE_SEPARATOR_BITS(START, WIDTH) NULL, START, WIDTH -#define DECODE_NEW_TABLE_HELPER(TAG, SIZE, FN, START, WIDTH) \ - static const DectreeTable dectree_table_##TAG =3D { \ - .size =3D SIZE, \ - .lookup_function =3D FN, \ - .startbit =3D START, \ - .width =3D WIDTH, \ - .table =3D { -#define DECODE_NEW_TABLE(TAG, SIZE, WHATNOT) \ - DECODE_NEW_TABLE_HELPER(TAG, SIZE, WHATNOT) - -#define TABLE_LINK(TABLE) \ - { .type =3D DECTREE_TABLE_LINK, .table_link =3D &dectree_table_##TABLE= }, -#define TERMINAL(TAG, ENC) \ - { .type =3D DECTREE_TERMINAL, .opcode =3D TAG }, -#define SUBINSNS(TAG, CLASSA, CLASSB, ENC) \ - { \ - .type =3D DECTREE_SUBINSNS, \ - .table_link =3D &dectree_table_DECODE_SUBINSN_##CLASSA, \ - .table_link_b =3D &dectree_table_DECODE_SUBINSN_##CLASSB \ - }, -#define EXTSPACE(TAG, ENC) { .type =3D DECTREE_EXTSPACE }, -#define INVALID() { .type =3D DECTREE_ENTRY_INVALID, .opcode =3D XX_LAST_O= PCODE }, - -#define DECODE_END_TABLE(...) } }; - -#define DECODE_MATCH_INFO(...) /* NOTHING */ -#define DECODE_LEGACY_MATCH_INFO(...) /* NOTHING */ -#define DECODE_OPINFO(...) /* NOTHING */ - -#include "dectree_generated.h.inc" - -#undef DECODE_OPINFO -#undef DECODE_MATCH_INFO -#undef DECODE_LEGACY_MATCH_INFO -#undef DECODE_END_TABLE -#undef INVALID -#undef TERMINAL -#undef SUBINSNS -#undef EXTSPACE -#undef TABLE_LINK -#undef DECODE_NEW_TABLE -#undef DECODE_NEW_TABLE_HELPER -#undef DECODE_SEPARATOR_BITS - -static const DectreeTable dectree_table_DECODE_EXT_EXT_noext =3D { - .size =3D 1, .lookup_function =3D NULL, .startbit =3D 0, .width =3D 0, - .table =3D { - { .type =3D DECTREE_ENTRY_INVALID, .opcode =3D XX_LAST_OPCODE }, - } -}; - -static const DectreeTable *ext_trees[XX_LAST_EXT_IDX]; - -static void decode_ext_init(void) -{ - int i; - for (i =3D EXT_IDX_noext; i < EXT_IDX_noext_AFTER; i++) { - ext_trees[i] =3D &dectree_table_DECODE_EXT_EXT_noext; - } - for (i =3D EXT_IDX_mmvec; i < EXT_IDX_mmvec_AFTER; i++) { - ext_trees[i] =3D &dectree_table_DECODE_EXT_EXT_mmvec; - } -} - -typedef struct { - uint32_t mask; - uint32_t match; -} DecodeITableEntry; - -#define DECODE_NEW_TABLE(TAG, SIZE, WHATNOT) /* NOTHING */ -#define TABLE_LINK(TABLE) /* NOTHING */ -#define TERMINAL(TAG, ENC) /* NOTHING */ -#define SUBINSNS(TAG, CLASSA, CLASSB, ENC) /* NOTHING */ -#define EXTSPACE(TAG, ENC) /* NOTHING */ -#define INVALID() /* NOTHING */ -#define DECODE_END_TABLE(...) /* NOTHING */ -#define DECODE_OPINFO(...) /* NOTHING */ - -#define DECODE_MATCH_INFO_NORMAL(TAG, MASK, MATCH) \ - [TAG] =3D { \ - .mask =3D MASK, \ - .match =3D MATCH, \ - }, - -#define DECODE_MATCH_INFO_NULL(TAG, MASK, MATCH) \ - [TAG] =3D { .match =3D ~0 }, - -#define DECODE_MATCH_INFO(...) DECODE_MATCH_INFO_NORMAL(__VA_ARGS__) -#define DECODE_LEGACY_MATCH_INFO(...) /* NOTHING */ - -static const DecodeITableEntry decode_itable[XX_LAST_OPCODE] =3D { -#include "dectree_generated.h.inc" -}; - -#undef DECODE_MATCH_INFO -#define DECODE_MATCH_INFO(...) DECODE_MATCH_INFO_NULL(__VA_ARGS__) - -#undef DECODE_LEGACY_MATCH_INFO -#define DECODE_LEGACY_MATCH_INFO(...) DECODE_MATCH_INFO_NORMAL(__VA_ARGS__) - -static const DecodeITableEntry decode_legacy_itable[XX_LAST_OPCODE] =3D { -#include "dectree_generated.h.inc" -}; - -#undef DECODE_OPINFO -#undef DECODE_MATCH_INFO -#undef DECODE_LEGACY_MATCH_INFO -#undef DECODE_END_TABLE -#undef INVALID -#undef TERMINAL -#undef SUBINSNS -#undef EXTSPACE -#undef TABLE_LINK -#undef DECODE_NEW_TABLE -#undef DECODE_SEPARATOR_BITS - -void decode_init(void) -{ - decode_ext_init(); -} - void decode_send_insn_to(Packet *packet, int start, int newloc) { Insn tmpinsn; @@ -587,7 +418,6 @@ apply_extender(Packet *pkt, int i, uint32_t extender) uint32_t base_immed; =20 immed_num =3D pkt->insn[i].which_extended; - g_assert(immed_num =3D=3D opcode_which_immediate_is_extended(pkt->insn= [i].opcode)); base_immed =3D pkt->insn[i].immed[immed_num]; =20 pkt->insn[i].immed[immed_num] =3D extender | fZXTN(6, 32, base_immed); @@ -630,174 +460,6 @@ static SlotMask get_valid_slots(const Packet *pkt, un= signed int slot) } } =20 -#define DECODE_NEW_TABLE(TAG, SIZE, WHATNOT) /* NOTHING */ -#define TABLE_LINK(TABLE) /* NOTHING */ -#define TERMINAL(TAG, ENC) /* NOTHING */ -#define SUBINSNS(TAG, CLASSA, CLASSB, ENC) /* NOTHING */ -#define EXTSPACE(TAG, ENC) /* NOTHING */ -#define INVALID() /* NOTHING */ -#define DECODE_END_TABLE(...) /* NOTHING */ -#define DECODE_MATCH_INFO(...) /* NOTHING */ -#define DECODE_LEGACY_MATCH_INFO(...) /* NOTHING */ - -#define DECODE_REG(REGNO, WIDTH, STARTBIT) \ - insn->regno[REGNO] =3D ((encoding >> STARTBIT) & ((1 << WIDTH) - 1)); - -#define DECODE_IMPL_REG(REGNO, VAL) \ - insn->regno[REGNO] =3D VAL; - -#define DECODE_IMM(IMMNO, WIDTH, STARTBIT, VALSTART) \ - insn->immed[IMMNO] |=3D (((encoding >> STARTBIT) & ((1 << WIDTH) - 1))= ) << \ - (VALSTART); - -#define DECODE_IMM_SXT(IMMNO, WIDTH) \ - insn->immed[IMMNO] =3D ((((int32_t)insn->immed[IMMNO]) << (32 - WIDTH)= ) >> \ - (32 - WIDTH)); - -#define DECODE_IMM_NEG(IMMNO, WIDTH) \ - insn->immed[IMMNO] =3D -insn->immed[IMMNO]; - -#define DECODE_IMM_SHIFT(IMMNO, SHAMT) \ - if ((!insn->extension_valid) || \ - (insn->which_extended !=3D IMMNO)) { \ - insn->immed[IMMNO] <<=3D SHAMT; \ - } - -#define DECODE_OPINFO(TAG, BEH) \ - case TAG: \ - { BEH } \ - break; \ - -/* - * Fill in the operands of the instruction - * dectree_generated.h.inc has a DECODE_OPINFO entry for each opcode - * For example, - * DECODE_OPINFO(A2_addi, - * DECODE_REG(0,5,0) - * DECODE_REG(1,5,16) - * DECODE_IMM(0,7,21,9) - * DECODE_IMM(0,9,5,0) - * DECODE_IMM_SXT(0,16) - * with the macros defined above, we'll fill in a switch statement - * where each case is an opcode tag. - */ -static void -decode_op(Insn *insn, Opcode tag, uint32_t encoding) -{ - insn->immed[0] =3D 0; - insn->immed[1] =3D 0; - insn->opcode =3D tag; - if (insn->extension_valid) { - insn->which_extended =3D opcode_which_immediate_is_extended(tag); - } - - switch (tag) { -#include "dectree_generated.h.inc" - default: - break; - } - - insn->generate =3D opcode_genptr[tag]; - - insn->iclass =3D iclass_bits(encoding); -} - -#undef DECODE_REG -#undef DECODE_IMPL_REG -#undef DECODE_IMM -#undef DECODE_IMM_SHIFT -#undef DECODE_OPINFO -#undef DECODE_MATCH_INFO -#undef DECODE_LEGACY_MATCH_INFO -#undef DECODE_END_TABLE -#undef INVALID -#undef TERMINAL -#undef SUBINSNS -#undef EXTSPACE -#undef TABLE_LINK -#undef DECODE_NEW_TABLE -#undef DECODE_SEPARATOR_BITS - -static unsigned int -decode_subinsn_tablewalk(Insn *insn, const DectreeTable *table, - uint32_t encoding) -{ - unsigned int i; - Opcode opc; - if (table->lookup_function) { - i =3D table->lookup_function(table->startbit, table->width, encodi= ng); - } else { - i =3D extract32(encoding, table->startbit, table->width); - } - if (table->table[i].type =3D=3D DECTREE_TABLE_LINK) { - return decode_subinsn_tablewalk(insn, table->table[i].table_link, - encoding); - } else if (table->table[i].type =3D=3D DECTREE_TERMINAL) { - opc =3D table->table[i].opcode; - if ((encoding & decode_itable[opc].mask) !=3D decode_itable[opc].m= atch) { - return 0; - } - decode_op(insn, opc, encoding); - return 1; - } else { - return 0; - } -} - -static unsigned int get_insn_a(uint32_t encoding) -{ - return extract32(encoding, 0, 13); -} - -static unsigned int get_insn_b(uint32_t encoding) -{ - return extract32(encoding, 16, 13); -} - -static unsigned int -decode_insns_tablewalk(Insn *insn, const DectreeTable *table, - uint32_t encoding) -{ - unsigned int i; - unsigned int a, b; - Opcode opc; - if (table->lookup_function) { - i =3D table->lookup_function(table->startbit, table->width, encodi= ng); - } else { - i =3D extract32(encoding, table->startbit, table->width); - } - if (table->table[i].type =3D=3D DECTREE_TABLE_LINK) { - return decode_insns_tablewalk(insn, table->table[i].table_link, - encoding); - } else if (table->table[i].type =3D=3D DECTREE_SUBINSNS) { - a =3D get_insn_a(encoding); - b =3D get_insn_b(encoding); - b =3D decode_subinsn_tablewalk(insn, table->table[i].table_link_b,= b); - a =3D decode_subinsn_tablewalk(insn + 1, table->table[i].table_lin= k, a); - if ((a =3D=3D 0) || (b =3D=3D 0)) { - return 0; - } - return 2; - } else if (table->table[i].type =3D=3D DECTREE_TERMINAL) { - opc =3D table->table[i].opcode; - if ((encoding & decode_itable[opc].mask) !=3D decode_itable[opc].m= atch) { - if ((encoding & decode_legacy_itable[opc].mask) !=3D - decode_legacy_itable[opc].match) { - return 0; - } - } - 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; - } -} - /* * Section 10.3 of the Hexagon V73 Programmer's Reference Manual * @@ -858,7 +520,6 @@ static uint16_t get_slot1_subinsn(uint32_t encoding) static unsigned int decode_insns(DisasContext *ctx, Insn *insn, uint32_t encoding) { - const DectreeTable *table; if (parse_bits(encoding) !=3D 0) { if (decode_normal(ctx, encoding) || decode_hvx(ctx, encoding)) { @@ -866,8 +527,6 @@ decode_insns(DisasContext *ctx, Insn *insn, uint32_t en= coding) insn->iclass =3D iclass_bits(encoding); return 1; } - /* Start with PP table - 32 bit instructions */ - table =3D &dectree_table_DECODE_ROOT_32; g_assert_not_reached(); } else { uint32_t iclass =3D get_duplex_iclass(encoding); @@ -889,11 +548,8 @@ decode_insns(DisasContext *ctx, Insn *insn, uint32_t e= ncoding) return 2; } } - /* start with EE table - duplex instructions */ - table =3D &dectree_table_DECODE_ROOT_EE; g_assert_not_reached(); } - return decode_insns_tablewalk(insn, table, encoding); } =20 static void decode_add_endloop_insn(Insn *insn, int loopnum) diff --git a/target/hexagon/gen_dectree_import.c b/target/hexagon/gen_dectr= ee_import.c index ee354677fd..87f20c14f1 100644 --- a/target/hexagon/gen_dectree_import.c +++ b/target/hexagon/gen_dectree_import.c @@ -56,24 +56,6 @@ const char * const opcode_syntax[XX_LAST_OPCODE] =3D { #undef EXTINSN }; =20 -const char * const opcode_rregs[] =3D { -#define REGINFO(TAG, REGINFO, RREGS, WREGS) RREGS, -#define IMMINFO(TAG, SIGN, SIZE, SHAMT, SIGN2, SIZE2, SHAMT2) /* nothing = */ -#include "op_regs_generated.h.inc" - NULL -#undef REGINFO -#undef IMMINFO -}; - -const char * const opcode_wregs[] =3D { -#define REGINFO(TAG, REGINFO, RREGS, WREGS) WREGS, -#define IMMINFO(TAG, SIGN, SIZE, SHAMT, SIGN2, SIZE2, SHAMT2) /* nothing = */ -#include "op_regs_generated.h.inc" - NULL -#undef REGINFO -#undef IMMINFO -}; - const OpcodeEncoding opcode_encodings[] =3D { #define DEF_ENC32(TAG, ENCSTR) \ [TAG] =3D { .encoding =3D ENCSTR }, @@ -130,8 +112,6 @@ static void gen_iset_table(FILE *out) fprintf(out, "\t\'%s\' : {\n", opcode_names[i]); fprintf(out, "\t\t\'tag\' : \'%s\',\n", opcode_names[i]); fprintf(out, "\t\t\'syntax\' : \'%s\',\n", opcode_syntax[i]); - fprintf(out, "\t\t\'rregs\' : \'%s\',\n", opcode_rregs[i]); - fprintf(out, "\t\t\'wregs\' : \'%s\',\n", opcode_wregs[i]); fprintf(out, "\t\t\'enc\' : \'%s\',\n", get_opcode_enc(i)); fprintf(out, "\t\t\'enc_class\' : \'%s\',\n", get_opcode_enc_class= (i)); fprintf(out, "\t},\n"); @@ -150,33 +130,6 @@ static void gen_tags_list(FILE *out) fprintf(out, "];\n\n"); } =20 -static void gen_enc_ext_spaces_table(FILE *out) -{ - fprintf(out, "enc_ext_spaces =3D {\n"); -#define DEF_EXT_SPACE(SPACEID, ENCSTR) \ - fprintf(out, "\t\'%s\' : \'%s\',\n", #SPACEID, ENCSTR); -#include "imported/encode.def" -#undef DEF_EXT_SPACE - fprintf(out, "};\n\n"); -} - -static void gen_subinsn_groupings_table(FILE *out) -{ - fprintf(out, "subinsn_groupings =3D {\n"); -#define DEF_PACKED32(TAG, TYPEA, TYPEB, ENCSTR) \ - do { \ - fprintf(out, "\t\'%s\' : {\n", #TAG); \ - fprintf(out, "\t\t\'name\' : \'%s\',\n", #TAG); \ - fprintf(out, "\t\t\'class_a\' : \'%s\',\n", #TYPEA); \ - fprintf(out, "\t\t\'class_b\' : \'%s\',\n", #TYPEB); \ - fprintf(out, "\t\t\'enc\' : \'%s\',\n", ENCSTR); \ - fprintf(out, "\t},\n"); \ - } while (0); -#include "imported/encode.def" -#undef DEF_PACKED32 - fprintf(out, "};\n\n"); -} - int main(int argc, char *argv[]) { FILE *outfile; @@ -193,8 +146,6 @@ int main(int argc, char *argv[]) =20 gen_iset_table(outfile); gen_tags_list(outfile); - gen_enc_ext_spaces_table(outfile); - gen_subinsn_groupings_table(outfile); =20 fclose(outfile); return 0; diff --git a/target/hexagon/opcodes.c b/target/hexagon/opcodes.c index 35d790cdd5..1f7f3def38 100644 --- a/target/hexagon/opcodes.c +++ b/target/hexagon/opcodes.c @@ -111,33 +111,4 @@ void opcode_init(void) #include "op_attribs_generated.h.inc" #undef OP_ATTRIB #undef ATTRIBS - - decode_init(); -} - - -#define NEEDLE "IMMEXT(" - -int opcode_which_immediate_is_extended(Opcode opcode) -{ - const char *p; - - g_assert(opcode < XX_LAST_OPCODE); - g_assert(GET_ATTRIB(opcode, A_EXTENDABLE)); - - p =3D opcode_short_semantics[opcode]; - p =3D strstr(p, NEEDLE); - g_assert(p); - p +=3D strlen(NEEDLE); - while (isspace(*p)) { - p++; - } - /* lower is always imm 0, upper always imm 1. */ - if (islower(*p)) { - return 0; - } else if (isupper(*p)) { - return 1; - } else { - g_assert_not_reached(); - } } diff --git a/target/hexagon/dectree.py b/target/hexagon/dectree.py deleted file mode 100755 index 3b32948a04..0000000000 --- a/target/hexagon/dectree.py +++ /dev/null @@ -1,403 +0,0 @@ -#!/usr/bin/env python3 - -## -## Copyright(c) 2019-2023 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 . -## - -import io -import re - -import sys -import iset - -encs =3D { - tag: "".join(reversed(iset.iset[tag]["enc"].replace(" ", ""))) - for tag in iset.tags - if iset.iset[tag]["enc"] !=3D "MISSING ENCODING" -} - -enc_classes =3D set([iset.iset[tag]["enc_class"] for tag in encs.keys()]) -subinsn_enc_classes =3D set( - [enc_class for enc_class in enc_classes if enc_class.startswith("SUBIN= SN_")] -) -ext_enc_classes =3D set( - [ - enc_class - for enc_class in enc_classes - if enc_class not in ("NORMAL", "16BIT") and not enc_class.startswi= th("SUBINSN_") - ] -) - -try: - subinsn_groupings =3D iset.subinsn_groupings -except AttributeError: - subinsn_groupings =3D {} - -for tag, subinsn_grouping in subinsn_groupings.items(): - encs[tag] =3D "".join(reversed(subinsn_grouping["enc"].replace(" ", ""= ))) - -dectree_normal =3D {"leaves": set()} -dectree_16bit =3D {"leaves": set()} -dectree_subinsn_groupings =3D {"leaves": set()} -dectree_subinsns =3D {name: {"leaves": set()} for name in subinsn_enc_clas= ses} -dectree_extensions =3D {name: {"leaves": set()} for name in ext_enc_classe= s} - -for tag in encs.keys(): - if tag in subinsn_groupings: - dectree_subinsn_groupings["leaves"].add(tag) - continue - enc_class =3D iset.iset[tag]["enc_class"] - if enc_class.startswith("SUBINSN_"): - if len(encs[tag]) !=3D 32: - encs[tag] =3D encs[tag] + "0" * (32 - len(encs[tag])) - dectree_subinsns[enc_class]["leaves"].add(tag) - elif enc_class =3D=3D "16BIT": - if len(encs[tag]) !=3D 16: - raise Exception( - 'Tag "{}" has enc_class "{}" and not an encoding ' - + "width of 16 bits!".format(tag, enc_class) - ) - dectree_16bit["leaves"].add(tag) - else: - if len(encs[tag]) !=3D 32: - raise Exception( - 'Tag "{}" has enc_class "{}" and not an encoding ' - + "width of 32 bits!".format(tag, enc_class) - ) - if enc_class =3D=3D "NORMAL": - dectree_normal["leaves"].add(tag) - else: - dectree_extensions[enc_class]["leaves"].add(tag) - -faketags =3D set() -for tag, enc in iset.enc_ext_spaces.items(): - faketags.add(tag) - encs[tag] =3D "".join(reversed(enc.replace(" ", ""))) - dectree_normal["leaves"].add(tag) - -faketags |=3D set(subinsn_groupings.keys()) - - -def every_bit_counts(bitset): - for i in range(1, len(next(iter(bitset)))): - if len(set([bits[:i] + bits[i + 1 :] for bits in bitset])) =3D=3D = len(bitset): - return False - return True - - -def auto_separate(node): - tags =3D node["leaves"] - if len(tags) <=3D 1: - return - enc_width =3D len(encs[next(iter(tags))]) - opcode_bit_for_all =3D [ - all([encs[tag][i] in "01" for tag in tags]) for i in range(enc_wid= th) - ] - opcode_bit_is_0_for_all =3D [ - opcode_bit_for_all[i] and all([encs[tag][i] =3D=3D "0" for tag in = tags]) - for i in range(enc_width) - ] - opcode_bit_is_1_for_all =3D [ - opcode_bit_for_all[i] and all([encs[tag][i] =3D=3D "1" for tag in = tags]) - for i in range(enc_width) - ] - differentiator_opcode_bit =3D [ - opcode_bit_for_all[i] - and not (opcode_bit_is_0_for_all[i] or opcode_bit_is_1_for_all[i]) - for i in range(enc_width) - ] - best_width =3D 0 - for width in range(4, 0, -1): - for lsb in range(enc_width - width, -1, -1): - bitset =3D set([encs[tag][lsb : lsb + width] for tag in tags]) - if all(differentiator_opcode_bit[lsb : lsb + width]) and ( - len(bitset) =3D=3D len(tags) or every_bit_counts(bitset) - ): - best_width =3D width - best_lsb =3D lsb - caught_all_tags =3D len(bitset) =3D=3D len(tags) - break - if best_width !=3D 0: - break - if best_width =3D=3D 0: - raise Exception( - "Could not find a way to differentiate the encodings " - + "of the following tags:\n{}".format("\n".join(tags)) - ) - if caught_all_tags: - for width in range(1, best_width): - for lsb in range(enc_width - width, -1, -1): - bitset =3D set([encs[tag][lsb : lsb + width] for tag in ta= gs]) - if all(differentiator_opcode_bit[lsb : lsb + width]) and l= en( - bitset - ) =3D=3D len(tags): - best_width =3D width - best_lsb =3D lsb - break - else: - continue - break - node["separator_lsb"] =3D best_lsb - node["separator_width"] =3D best_width - node["children"] =3D [] - for value in range(2**best_width): - child =3D {} - bits =3D "".join(reversed("{:0{}b}".format(value, best_width))) - child["leaves"] =3D set( - [tag for tag in tags if encs[tag][best_lsb : best_lsb + best_w= idth] =3D=3D bits] - ) - node["children"].append(child) - for child in node["children"]: - auto_separate(child) - - -auto_separate(dectree_normal) -auto_separate(dectree_16bit) -if subinsn_groupings: - auto_separate(dectree_subinsn_groupings) -for dectree_subinsn in dectree_subinsns.values(): - auto_separate(dectree_subinsn) -for dectree_ext in dectree_extensions.values(): - auto_separate(dectree_ext) - -for tag in faketags: - del encs[tag] - - -def table_name(parents, node): - path =3D parents + [node] - root =3D path[0] - tag =3D next(iter(node["leaves"])) - if tag in subinsn_groupings: - enc_width =3D len(subinsn_groupings[tag]["enc"].replace(" ", "")) - else: - tag =3D next(iter(node["leaves"] - faketags)) - enc_width =3D len(encs[tag]) - determining_bits =3D ["_"] * enc_width - for parent, child in zip(path[:-1], path[1:]): - lsb =3D parent["separator_lsb"] - width =3D parent["separator_width"] - value =3D parent["children"].index(child) - determining_bits[lsb : lsb + width] =3D list( - reversed("{:0{}b}".format(value, width)) - ) - if tag in subinsn_groupings: - name =3D "DECODE_ROOT_EE" - else: - enc_class =3D iset.iset[tag]["enc_class"] - if enc_class in ext_enc_classes: - name =3D "DECODE_EXT_{}".format(enc_class) - elif enc_class in subinsn_enc_classes: - name =3D "DECODE_SUBINSN_{}".format(enc_class) - else: - name =3D "DECODE_ROOT_{}".format(enc_width) - if node !=3D root: - name +=3D "_" + "".join(reversed(determining_bits)) - return name - - -def print_node(f, node, parents): - if len(node["leaves"]) <=3D 1: - return - name =3D table_name(parents, node) - lsb =3D node["separator_lsb"] - width =3D node["separator_width"] - print( - "DECODE_NEW_TABLE({},{},DECODE_SEPARATOR_BITS({},{}))".format( - name, 2**width, lsb, width - ), - file=3Df, - ) - for child in node["children"]: - if len(child["leaves"]) =3D=3D 0: - print("INVALID()", file=3Df) - elif len(child["leaves"]) =3D=3D 1: - (tag,) =3D child["leaves"] - if tag in subinsn_groupings: - class_a =3D subinsn_groupings[tag]["class_a"] - class_b =3D subinsn_groupings[tag]["class_b"] - enc =3D subinsn_groupings[tag]["enc"].replace(" ", "") - if "RESERVED" in tag: - print("INVALID()", file=3Df) - else: - print( - 'SUBINSNS({},{},{},"{}")'.format(tag, class_a, cla= ss_b, enc), - file=3Df, - ) - elif tag in iset.enc_ext_spaces: - enc =3D iset.enc_ext_spaces[tag].replace(" ", "") - print('EXTSPACE({},"{}")'.format(tag, enc), file=3Df) - else: - enc =3D "".join(reversed(encs[tag])) - print('TERMINAL({},"{}")'.format(tag, enc), file=3Df) - else: - print("TABLE_LINK({})".format(table_name(parents + [node], chi= ld)), file=3Df) - print( - "DECODE_END_TABLE({},{},DECODE_SEPARATOR_BITS({},{}))".format( - name, 2**width, lsb, width - ), - file=3Df, - ) - print(file=3Df) - parents.append(node) - for child in node["children"]: - print_node(f, child, parents) - parents.pop() - - -def print_tree(f, tree): - print_node(f, tree, []) - - -def print_match_info(f): - for tag in sorted(encs.keys(), key=3Diset.tags.index): - enc =3D "".join(reversed(encs[tag])) - mask =3D int(re.sub(r"[^1]", r"0", enc.replace("0", "1")), 2) - match =3D int(re.sub(r"[^01]", r"0", enc), 2) - suffix =3D "" - print( - "DECODE{}_MATCH_INFO({},0x{:x}U,0x{:x}U)".format(suffix, tag, = mask, match), - file=3Df, - ) - - -regre =3D re.compile(r"((? 1: - raise Exception('Tag "{}" has split register field!'.forma= t(tag)) - reg_enc_field =3D reg_enc_fields[0] - if 2 ** len(reg_enc_field) !=3D reg_num_choices: - raise Exception( - 'Tag "{}" has incorrect register field width!'.format(= tag) - ) - print( - " DECODE_REG({},{},{})".format( - regno, len(reg_enc_field), enc.index(reg_enc_field) - ), - file=3Df, - ) - if reg_type in num_registers and reg_num_choices !=3D num_regi= sters[reg_type]: - print( - " DECODE_MAPPED_REG({},{})".format(regno, reg_m= apping), - file=3Df, - ) - regno +=3D 1 - - def implicit_register_key(reg): - return implicit_registers[reg] - - for reg in sorted( - set( - [ - r - for r in ( - iset.iset[tag]["rregs"].split(",") - + iset.iset[tag]["wregs"].split(",") - ) - if r in implicit_registers - ] - ), - key=3Dimplicit_register_key, - ): - print( - " DECODE_IMPL_REG({},{})".format(regno, implicit_re= gisters[reg]), - file=3Df, - ) - regno +=3D 1 - if imms and imms[0][0].isupper(): - imms =3D reversed(imms) - for imm in imms: - if imm[0].isupper(): - immno =3D 1 - else: - immno =3D 0 - imm_type =3D imm[0] - imm_width =3D int(imm[1]) - imm_shift =3D imm[2] - if imm_shift: - imm_shift =3D int(imm_shift) - else: - imm_shift =3D 0 - if imm_type.islower(): - imm_letter =3D "i" - else: - imm_letter =3D "I" - remainder =3D imm_width - for m in reversed(list(re.finditer(imm_letter + "+", enc))): - remainder -=3D m.end() - m.start() - print( - " DECODE_IMM({},{},{},{})".format( - immno, m.end() - m.start(), m.start(), remainder - ), - file=3Df, - ) - if remainder !=3D 0: - if imm[2]: - imm[2] =3D ":" + imm[2] - raise Exception( - 'Tag "{}" has an incorrect number of ' - + 'encoding bits for immediate "{}"'.format(tag, "".jo= in(imm)) - ) - if imm_type.lower() in "sr": - print(" DECODE_IMM_SXT({},{})".format(immno, imm_wi= dth), file=3Df) - if imm_type.lower() =3D=3D "n": - print(" DECODE_IMM_NEG({},{})".format(immno, imm_wi= dth), file=3Df) - if imm_shift: - print( - " DECODE_IMM_SHIFT({},{})".format(immno, imm_sh= ift), file=3Df - ) - print(")", file=3Df) - - -if __name__ =3D=3D "__main__": - with open(sys.argv[1], "w") as f: - print_tree(f, dectree_normal) - print_tree(f, dectree_16bit) - if subinsn_groupings: - print_tree(f, dectree_subinsn_groupings) - for name, dectree_subinsn in sorted(dectree_subinsns.items()): - print_tree(f, dectree_subinsn) - for name, dectree_ext in sorted(dectree_extensions.items()): - print_tree(f, dectree_ext) - print_match_info(f) - print_op_info(f) diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build index 1bd1ebcba1..fb480afc03 100644 --- a/target/hexagon/meson.build +++ b/target/hexagon/meson.build @@ -122,18 +122,6 @@ hexagon_ss.add(iset_py) =20 # # Step 4 -# We use the dectree.py script to generate the decode tree header file -# -dectree_generated =3D custom_target( - 'dectree_generated.h.inc', - output: 'dectree_generated.h.inc', - depends: [iset_py], - env: {'PYTHONPATH': meson.current_build_dir()}, - command: [python, files('dectree.py'), '@OUTPUT@'], -) -hexagon_ss.add(dectree_generated) - -# # Generate the input to the QEMU decodetree.py script # normal_decode_generated =3D custom_target( --=20 2.34.1