From patchwork Tue Nov 15 04:52:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tsukasa OI X-Patchwork-Id: 20190 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a40e:b0:83:7221:86ba with SMTP id ck14csp3424381dyb; Mon, 14 Nov 2022 21:01:04 -0800 (PST) X-Google-Smtp-Source: AA0mqf5O2/viroqEwZHheLsFT6bfZ+dQbyXGJERZMEj2jyTECUY55sFELQLHAcCqduPYiRyoKf/E X-Received: by 2002:aa7:de88:0:b0:458:b42e:46e6 with SMTP id j8-20020aa7de88000000b00458b42e46e6mr13766419edv.375.1668488463879; Mon, 14 Nov 2022 21:01:03 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668488463; cv=none; d=google.com; s=arc-20160816; b=laWnhFwmbeAd3XT5Z8wU7e89SPqDecJFcAjHEfpy56Vy6ZVNzDv43wLmjBoUAGHAL7 oy5ucaqkpmeqRTyo0RhZGYwgpKl/uBAkNIkt9L2FeROciOkQZ4nSCXpUY4+cTPEU0jPx KmjvWaFiGhGGwd9xrhvdLVY8P+w3GE1k4BytL/BL41wD1DE38hp+Ae/YLSxuznC0hHSc c6pz6JUK344z3wqH6PLpEod+TRTzy3McROqhMhj4SGNqfy5t7p34L+ioaVB5/Ei4UWsS ar8vdk6hpW65IUzVkgLGLJ+eJ1zj3T5c3u2kcqyUL5EWyvagkY+44b8N5OMZ00yuWhrK t1LQ== 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=rH8mxvEGOFghryGPjYWDBEhxXyhVT3aW5oEj3Y+hF9s=; b=n0KKcFi1nIGajJOdUkLk63hG9FvZ2+k7jk9p8hAJpKdKp9vZfLm9KZUPy1dCxsZAxx vHOsDbHBFVKQt3Js2qXjQbmcCAa3E6xXGoOc2N66lAiHhoQPyPghw3woV4Ml/k2Tg4UI b3y4QC1At5s282eTsbHl78GRixTAUyxwekBlBkmDRgjNXNK0xufQ0bdxdbhlh5XMfOKu f0grnKJrsoH85dVmKovVmfQSgDmCvFFzvnOTyvXvHMEBSrKlRuIMDtUHWqG98OPgStqk iQNPNnB3sAcsD/HjI0nuqxNbgz+raRSXo57M4FzrxfwgO1eXEYBYNsd7kczEs4G4cMhh rovQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=AtplthCW; 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 j10-20020a05640211ca00b00454599abf52si12682699edw.92.2022.11.14.21.01.03 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Nov 2022 21:01:03 -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=AtplthCW; 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 7D319382EF28 for ; Tue, 15 Nov 2022 04:59:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7D319382EF28 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1668488360; bh=rH8mxvEGOFghryGPjYWDBEhxXyhVT3aW5oEj3Y+hF9s=; 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=AtplthCWcpKUMNEB6HMog+SwGIPHc7stHnxUVR9ImrEfwyUVnnatTdBTHUSd3wpEg Do0t9NzP4Rk+5WqpR2VQWq1KWa3pThnbgN5KKVyPhTPntEU1VNif3yZKK1cKZ2cICi cm1WKiSaa+XuksGkvZUj6pTwb95TpmQv9kxqnBDQ= 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 07538382D39F for ; Tue, 15 Nov 2022 04:58:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 07538382D39F Received: from [127.0.0.1] (localhost [127.0.0.1]) by mail-sender-0.a4lg.com (Postfix) with ESMTPSA id 5A277300089; Tue, 15 Nov 2022 04:58:57 +0000 (UTC) To: Tsukasa OI , Nelson Chu , Kito Cheng , Palmer Dabbelt Cc: binutils@sourceware.org Subject: [PATCH 08/11] RISC-V: Split match/print steps on disassembler Date: Tue, 15 Nov 2022 04:52:51 +0000 Message-Id: <1352fb8c63539727204df94651f371ed09bbce4c.1668487922.git.research_trasio@irq.a4lg.com> 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?1749536959919471200?= 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 d9c16dad615..316c6c97607 100644 --- a/opcodes/riscv-dis.c +++ b/opcodes/riscv-dis.c @@ -646,7 +646,7 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info static int riscv_disassemble_insn (bfd_vma memaddr, insn_t word, 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; @@ -702,85 +702,92 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info) 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. */