From patchwork Fri Nov 13 07:27:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kito Cheng X-Patchwork-Id: 1399574 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sifive.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=sifive.com header.i=@sifive.com header.a=rsa-sha256 header.s=google header.b=HtrVOcpZ; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CXVSH0Cl2z9sTR for ; Fri, 13 Nov 2020 18:28:15 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id EFE143A1603F; Fri, 13 Nov 2020 07:28:12 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pg1-x52d.google.com (mail-pg1-x52d.google.com [IPv6:2607:f8b0:4864:20::52d]) by sourceware.org (Postfix) with ESMTPS id 3E3E0383F846 for ; Fri, 13 Nov 2020 07:28:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 3E3E0383F846 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=sifive.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=kito.cheng@sifive.com Received: by mail-pg1-x52d.google.com with SMTP id w4so6370119pgg.13 for ; Thu, 12 Nov 2020 23:28:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references:reply-to :mime-version:content-transfer-encoding; bh=a7gFhbIN0f91wjpfvtp95P0m13pVCCTFocx0Vg1eL9M=; b=HtrVOcpZ8sDhaGf/XUYV9+l+YurAc15vxS3vaeXmaCFR92FrpPZIAPqnXFic263D8F 3vq8P1GlM74yE0moFIxdmC31lpuhtSJ29iCPIz96mPr1xyHaJ5lS1yqer5DEp+GIx0bF x04SiVqi5Q2k4dUSnSjxI2CLAApt6FzLYLxbhSZDwAruF4qaJ+kL+1imCuGNKQN2wsxj DmH6VInGmBUURKA1tnUodLDgC40nS5O8SG25wKcLGoa6mNQkDjGlDeLQgk96k+6m3TTT upDu0/iJYhQfE+76cyhuHMi4Mxsj0fDaRreT01G/zToLUO2fymWbzMBGxJtxS4jCPQcw MmAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:reply-to:mime-version:content-transfer-encoding; bh=a7gFhbIN0f91wjpfvtp95P0m13pVCCTFocx0Vg1eL9M=; b=rZ2OC1mC87/bU2IqUWR+h7+niFsdLkr8yIjQLK+w/H+K3UsARKe+9urHxx/rVCDAMH yib234bsbu64rCZ05VJyc2UCrgbWNUwqUcgWD8zCba/lRgTfcLWfkHmLxeYNPNufYt0d bZA1grnbIWjrZj34aTDZaWO6SPePX/ZRCrRAzBbfDG0xjC6wJUO+NBWPjXSYP+aQDJua d6rnTQpB6D69Bf3dG0/fPnCqfLYYK11xRrpK7QD2hjXyZCuAxRq2npMKcNcbGJmzB3E7 YyHmDpo9ngYzoYQsmlGfaUChLfHuy+Nu4ih6TaeVyhPvk8o80rp+ROqMUID/lkYMzBm4 X9PA== X-Gm-Message-State: AOAM5311yj2OlJ3EDQ0xcunQ1mhc6do+Acz6wU62HPG//c3lcEJgz71V x406NQ5i0IgF8BG1GpsnkuNmLAbWMZpr4g== X-Google-Smtp-Source: ABdhPJxBQ2pXTfwZJWQ9K7WMwYcRcbc1P/BWXt1YRE2PoQctV/AY3aQH++LXWCohuMNLjNBMlpY+XQ== X-Received: by 2002:a62:f809:0:b029:18e:f528:76e6 with SMTP id d9-20020a62f8090000b029018ef52876e6mr1021735pfh.28.1605252488885; Thu, 12 Nov 2020 23:28:08 -0800 (PST) Received: from hsinchu02.internal.sifive.com (114-34-229-221.HINET-IP.hinet.net. [114.34.229.221]) by smtp.gmail.com with ESMTPSA id e7sm7987405pgj.19.2020.11.12.23.28.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 12 Nov 2020 23:28:08 -0800 (PST) From: Kito Cheng To: gcc-patches@gcc.gnu.org, kito.cheng@gmail.com Subject: [PATCH 1/3] RISC-V: Handle implied extension in canonical ordering. Date: Fri, 13 Nov 2020 15:27:40 +0800 Message-Id: <20201113072742.41983-2-kito.cheng@sifive.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201113072742.41983-1-kito.cheng@sifive.com> References: <20201113072742.41983-1-kito.cheng@sifive.com> MIME-Version: 1.0 X-Spam-Status: No, score=-14.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Kito Cheng Cc: Kito Cheng Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" - ISA spec has specify the order between multi-letter extensions, implied extension also need to follow store in canonical ordering, so most easy way is we keep that in-order during insertion. gcc/ChangeLog: * common/config/riscv/riscv-common.c (single_letter_subset_rank): New. (multi_letter_subset_rank): Ditto. (subset_cmp): Ditto. (riscv_subset_list::add): Insert subext in canonical ordering. (riscv_subset_list::parse_std_ext): Move handle_implied_ext to ... (riscv_subset_list::parse): ... here. --- gcc/common/config/riscv/riscv-common.c | 177 ++++++++++++++++++++++++- 1 file changed, 172 insertions(+), 5 deletions(-) diff --git a/gcc/common/config/riscv/riscv-common.c b/gcc/common/config/riscv/riscv-common.c index 9a576eb689b..f5f7be3cfff 100644 --- a/gcc/common/config/riscv/riscv-common.c +++ b/gcc/common/config/riscv/riscv-common.c @@ -145,6 +145,129 @@ riscv_subset_list::~riscv_subset_list () } } +/* Get the rank for single-letter subsets, lower value meaning higher + priority. */ + +static int +single_letter_subset_rank (char ext) +{ + int rank; + + switch (ext) + { + case 'i': + return 0; + case 'e': + return 1; + default: + break; + } + + const char *all_ext = riscv_supported_std_ext (); + const char *ext_pos = strchr (all_ext, ext); + if (ext_pos == NULL) + /* If got an unknown extension letter, then give it an alphabetical + order, but after all known standard extension. */ + rank = strlen (all_ext) + ext - 'a'; + else + rank = (int)(ext_pos - all_ext) + 2 /* e and i has higher rank. */; + + return rank; +} + +/* Get the rank for multi-letter subsets, lower value meaning higher + priority. */ + +static int +multi_letter_subset_rank (const std::string &subset) +{ + gcc_assert (subset.length () >= 2); + int high_order = -1; + int low_order = 0; + /* The order between multi-char extensions: s -> h -> z -> x. */ + char multiletter_class = subset[0]; + switch (multiletter_class) + { + case 's': + high_order = 0; + break; + case 'h': + high_order = 1; + break; + case 'z': + gcc_assert (subset.length () > 2); + high_order = 2; + break; + case 'x': + high_order = 3; + break; + default: + gcc_unreachable (); + return -1; + } + + if (multiletter_class == 'z') + /* Order for z extension on spec: If multiple "Z" extensions are named, they + should be ordered first by category, then alphabetically within a + category - for example, "Zicsr_Zifencei_Zam". */ + low_order = single_letter_subset_rank (subset[1]); + else + low_order = 0; + + return (high_order << 8) + low_order; +} + +/* subset compare + + Returns an integral value indicating the relationship between the subsets: + Return value indicates + -1 B has higher order than A. + 0 A and B are same subset. + 1 A has higher order than B. + +*/ + +static int +subset_cmp (const std::string &a, const std::string &b) +{ + if (a == b) + return 0; + + size_t a_len = a.length (); + size_t b_len = b.length (); + + /* Single-letter extension always get higher order than + multi-letter extension. */ + if (a_len == 1 && b_len != 1) + return 1; + + if (a_len != 1 && b_len == 1) + return -1; + + if (a_len == 1 && b_len == 1) + { + int rank_a = single_letter_subset_rank (a[0]); + int rank_b = single_letter_subset_rank (b[0]); + + if (rank_a < rank_b) + return 1; + else + return -1; + } + else + { + int rank_a = multi_letter_subset_rank(a); + int rank_b = multi_letter_subset_rank(b); + + /* Using alphabetical/lexicographical order if they have same rank. */ + if (rank_a == rank_b) + /* The return value of strcmp has opposite meaning. */ + return -strcmp (a.c_str (), b.c_str ()); + else + return (rank_a < rank_b) ? 1 : -1; + } +} + /* Add new subset to list. */ void @@ -152,6 +275,7 @@ riscv_subset_list::add (const char *subset, int major_version, int minor_version, bool explicit_version_p) { riscv_subset_t *s = new riscv_subset_t (); + riscv_subset_t *itr; if (m_head == NULL) m_head = s; @@ -162,9 +286,45 @@ riscv_subset_list::add (const char *subset, int major_version, s->explicit_version_p = explicit_version_p; s->next = NULL; - if (m_tail != NULL) - m_tail->next = s; + if (m_tail == NULL) + { + m_tail = s; + return; + } + + /* e, i or g should be first subext, never come here. */ + gcc_assert (subset[0] != 'e' + && subset[0] != 'i' + && subset[0] != 'g'); + + if (m_tail == m_head) + { + gcc_assert (m_head->next == NULL); + m_head->next = s; + m_tail = s; + return; + } + + gcc_assert (m_head->next != NULL); + + /* Subset list must in canonical order, but implied subset won't + add in canonical order. */ + for (itr = m_head; itr->next != NULL; itr = itr->next) + { + riscv_subset_t *next = itr->next; + int cmp = subset_cmp (s->name, next->name); + gcc_assert (cmp != 0); + + if (cmp > 0) + { + s->next = next; + itr->next = s; + return; + } + } + /* Insert at tail of the list. */ + itr->next = s; m_tail = s; } @@ -441,9 +601,6 @@ riscv_subset_list::parse_std_ext (const char *p) subset[0] = std_ext; - handle_implied_ext (subset, major_version, - minor_version, explicit_version_p); - add (subset, major_version, minor_version, explicit_version_p); } return p; @@ -553,6 +710,7 @@ riscv_subset_list * riscv_subset_list::parse (const char *arch, location_t loc) { riscv_subset_list *subset_list = new riscv_subset_list (arch, loc); + riscv_subset_t *itr; const char *p = arch; if (strncmp (p, "rv32", 4) == 0) { @@ -608,6 +766,15 @@ riscv_subset_list::parse (const char *arch, location_t loc) goto fail; } + for (itr = subset_list->m_head; itr != NULL; itr = itr->next) + { + subset_list->handle_implied_ext ( + itr->name.c_str (), + itr->major_version, + itr->minor_version, + itr->explicit_version_p); + } + return subset_list; fail: