From patchwork Mon Nov 28 04:43:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tsukasa OI X-Patchwork-Id: 26498 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp5433117wrr; Sun, 27 Nov 2022 20:47:19 -0800 (PST) X-Google-Smtp-Source: AA0mqf66tIlYcrtgWV9S/ZVjyjfotbjvGiYzNQcAXhRwO3WgNWN6vsNsWaOxQ3vvzneFjUStKuO3 X-Received: by 2002:a17:906:3c12:b0:7ad:7e81:1409 with SMTP id h18-20020a1709063c1200b007ad7e811409mr42072245ejg.326.1669610839397; Sun, 27 Nov 2022 20:47:19 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669610839; cv=none; d=google.com; s=arc-20160816; b=L5K/8qFlwDKNW/7pc7gRyOZ9A6iuJ8hTzfO2QsqZW73Wpq2OSttSInxlbYMMNxe5vx wVHPbLreaiLyfwvi7kNktnodwBcrYFAThl9NdM/iW9tjX9mXfGBh0NWXPSGOLfid1ehw Y82dIWqEqJufWBqAvMyRXp0LDN0iyTxZXtJQTlb1WeM9XE4Nk4uHLQEh3+FKzrHWCW9d CmGZPG/p3EI8UqpNYZEzZ9mfRMImme8FNEpt3x1Wo6ApfhifENZMns5Yi5WkoVLtiODo G/BUM2ZgGdUJCHNkglO923JEjxWZQKV/cjvOhAYavhSOtaVEEXyIszULZNvIWY6STlT5 Nhug== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:dmarc-filter:delivered-to :dkim-signature:dkim-filter; bh=yuHfLFlk929sqVLl7ONSiEsUZsFEQhVr1rqulntLglU=; b=blxGo8DHqeZmPPiaK31n+on40+AilXjjTNwChFBpvIq6dk3yCuuYwqhFd8cjxVt2AR 8A0WoDJY5VahPMrBOOdsk6YDiM4k2tuawczq+Xqc7ssbo5u9hpcFMlds5fKA4IPYsYiP xpHSAvJmZdPLzrhI7KLSGRHrONBWjpW0WHfAH94YqkcACRNjeIwBhyU4aSOl2jH/u1Ks OmF4fFnz8m5Ox+SdpBREpPm6HEyva7wBPlFtBCmDyH1VbpNho8DyC+72NWGB7TSwyUWE OsFmkIJx70WKS326ZXl2KbqtA+Ru2kpt4Eq0BdR+r9VyQP+oGBha2R4li19HWjSAemwH U/KA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=Au0LtLRC; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sourceware.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id z3-20020a1709067e4300b0078e1e77f443si7492328ejr.418.2022.11.27.20.47.19 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 27 Nov 2022 20:47:19 -0800 (PST) Received-SPF: pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=Au0LtLRC; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 196103889C9B for ; Mon, 28 Nov 2022 04:45:47 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 196103889C9B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1669610747; bh=yuHfLFlk929sqVLl7ONSiEsUZsFEQhVr1rqulntLglU=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=Au0LtLRCSWgh0zbZ/Xqgdyyqlv2cxD3siwQnp5D5bJH+bzeDo/Ov0W9QLQSNR7MlD uU1o50RFGUfQCuwJaiFV5SPYHdhOjC2R+HyTXkvGrZ6UKC8/QGpPDXAJQPpEqyw//y OQ07tuLnZBRGtYQdjZayK4QIy3AtXKhbX02wzD1c= X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-sender-0.a4lg.com (mail-sender-0.a4lg.com [IPv6:2401:2500:203:30b:4000:6bfe:4757:0]) by sourceware.org (Postfix) with ESMTPS id B9502384F6E2 for ; Mon, 28 Nov 2022 04:45:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B9502384F6E2 Received: from [127.0.0.1] (localhost [127.0.0.1]) by mail-sender-0.a4lg.com (Postfix) with ESMTPSA id 1C129300089; Mon, 28 Nov 2022 04:45:29 +0000 (UTC) To: Tsukasa OI , Nelson Chu , Kito Cheng , Palmer Dabbelt Cc: binutils@sourceware.org Subject: [PATCH v2 08/11] RISC-V: Split match/print steps on disassembler Date: Mon, 28 Nov 2022 04:43:43 +0000 Message-Id: In-Reply-To: References: Mime-Version: 1.0 X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tsukasa OI via Binutils From: Tsukasa OI Reply-To: Tsukasa OI Errors-To: binutils-bounces+ouuuleilei=gmail.com@sourceware.org Sender: "Binutils" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749536959919471200?= X-GMAIL-MSGID: =?utf-8?q?1750713855315084137?= From: Tsukasa OI For further optimization and more disassembler features, we may need to change the core RISC-V instruction matching. For this purpose, it is inconvenient to have "match" and "print" steps in the same loop. This commit rewrites riscv_disassemble_insn function so that we store matched_op for matching RISC-V opcode and then print it (if not NULL). Although it looks a bit inefficient, it also lowers the indent of opcode matching loop to clarify the opcode matching changes on the next optimization commit. Unfortunately, this commit alone will impose some performance penalty (<5% on most cases but sometimes about 15% worse) but it can be easily paid back by other optimizations. opcodes/ChangeLog: * riscv-dis.c (riscv_disassemble_insn): Split instruction handling to two separate steps - opcode matching and printing. --- opcodes/riscv-dis.c | 151 +++++++++++++++++++++++--------------------- 1 file changed, 79 insertions(+), 72 deletions(-) diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c index f5dc1907c6ec..c74827ed19df 100644 --- a/opcodes/riscv-dis.c +++ b/opcodes/riscv-dis.c @@ -649,7 +649,7 @@ riscv_disassemble_insn (bfd_vma memaddr, const bfd_byte *packet, disassemble_info *info) { - const struct riscv_opcode *op; + const struct riscv_opcode *op, *matched_op; static bool init = false; static const struct riscv_opcode *riscv_hash[OP_MASK_OP + 1]; struct riscv_private_data *pd; @@ -705,85 +705,92 @@ riscv_disassemble_insn (bfd_vma memaddr, info->target = 0; info->target2 = 0; + matched_op = NULL; op = riscv_hash[OP_HASH_IDX (word)]; - if (op != NULL) + + /* If XLEN is not known, get its value from the ELF class. */ + if (info->mach == bfd_mach_riscv64) + xlen = 64; + else if (info->mach == bfd_mach_riscv32) + xlen = 32; + else if (info->section != NULL) { - /* If XLEN is not known, get its value from the ELF class. */ - if (info->mach == bfd_mach_riscv64) - xlen = 64; - else if (info->mach == bfd_mach_riscv32) - xlen = 32; - else if (info->section != NULL) - { - Elf_Internal_Ehdr *ehdr = elf_elfheader (info->section->owner); - xlen = ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? 64 : 32; - } + Elf_Internal_Ehdr *ehdr = elf_elfheader (info->section->owner); + xlen = ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? 64 : 32; + } - /* If arch has the Zfinx extension, replace FPR with GPR. */ - if (riscv_subset_supports (&riscv_rps_dis, "zfinx")) - riscv_fpr_names = riscv_gpr_names; - else - riscv_fpr_names = riscv_gpr_names == riscv_gpr_names_abi ? - riscv_fpr_names_abi : riscv_fpr_names_numeric; + /* If arch has the Zfinx extension, replace FPR with GPR. */ + if (riscv_subset_supports (&riscv_rps_dis, "zfinx")) + riscv_fpr_names = riscv_gpr_names; + else + riscv_fpr_names = riscv_gpr_names == riscv_gpr_names_abi + ? riscv_fpr_names_abi + : riscv_fpr_names_numeric; - for (; op->name; op++) - { - /* Does the opcode match? */ - if (! (op->match_func) (op, word)) - continue; - /* Is this a pseudo-instruction and may we print it as such? */ - if (no_aliases && (op->pinfo & INSN_ALIAS)) - continue; - /* Is this instruction restricted to a certain value of XLEN? */ - if ((op->xlen_requirement != 0) && (op->xlen_requirement != xlen)) - continue; - /* Is this instruction supported by the current architecture? */ - if (!riscv_multi_subset_supports (&riscv_rps_dis, op->insn_class)) - continue; - - /* It's a match. */ - (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic, - "%s", op->name); - print_insn_args (op->args, word, memaddr, info); - - /* Try to disassemble multi-instruction addressing sequences. */ - if (pd->to_print_addr) - { - info->target = pd->print_addr; - (*info->fprintf_styled_func) - (info->stream, dis_style_comment_start, " # "); - (*info->print_address_func) (info->target, info); - pd->to_print_addr = false; - } + for (; op && op->name; op++) + { + /* Does the opcode match? */ + if (!(op->match_func) (op, word)) + continue; + /* Is this a pseudo-instruction and may we print it as such? */ + if (no_aliases && (op->pinfo & INSN_ALIAS)) + continue; + /* Is this instruction restricted to a certain value of XLEN? */ + if ((op->xlen_requirement != 0) && (op->xlen_requirement != xlen)) + continue; + /* Is this instruction supported by the current architecture? */ + if (!riscv_multi_subset_supports (&riscv_rps_dis, op->insn_class)) + continue; - /* Finish filling out insn_info fields. */ - switch (op->pinfo & INSN_TYPE) - { - case INSN_BRANCH: - info->insn_type = dis_branch; - break; - case INSN_CONDBRANCH: - info->insn_type = dis_condbranch; - break; - case INSN_JSR: - info->insn_type = dis_jsr; - break; - case INSN_DREF: - info->insn_type = dis_dref; - break; - default: - break; - } + matched_op = op; + break; + } - if (op->pinfo & INSN_DATA_SIZE) - { - int size = ((op->pinfo & INSN_DATA_SIZE) - >> INSN_DATA_SIZE_SHIFT); - info->data_size = 1 << (size - 1); - } + if (matched_op != NULL) + { + /* There is a match. */ + op = matched_op; + + (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic, + "%s", op->name); + print_insn_args (op->args, word, memaddr, info); - return insnlen; + /* Try to disassemble multi-instruction addressing sequences. */ + if (pd->to_print_addr) + { + info->target = pd->print_addr; + (*info->fprintf_styled_func) (info->stream, dis_style_comment_start, + " # "); + (*info->print_address_func) (info->target, info); + pd->to_print_addr = false; } + + /* Finish filling out insn_info fields. */ + switch (op->pinfo & INSN_TYPE) + { + case INSN_BRANCH: + info->insn_type = dis_branch; + break; + case INSN_CONDBRANCH: + info->insn_type = dis_condbranch; + break; + case INSN_JSR: + info->insn_type = dis_jsr; + break; + case INSN_DREF: + info->insn_type = dis_dref; + break; + default: + break; + } + + if (op->pinfo & INSN_DATA_SIZE) + { + int size = ((op->pinfo & INSN_DATA_SIZE) >> INSN_DATA_SIZE_SHIFT); + info->data_size = 1 << (size - 1); + } + + return insnlen; } /* We did not find a match, so just print the instruction bits. */