From patchwork Tue Oct 10 04:13:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kito Cheng X-Patchwork-Id: 1845590 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.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=DzkVz+iC; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.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 ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4S4Mwq2gCVz1yq7 for ; Tue, 10 Oct 2023 15:14:19 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 48473385C6FF for ; Tue, 10 Oct 2023 04:13:59 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pl1-x633.google.com (mail-pl1-x633.google.com [IPv6:2607:f8b0:4864:20::633]) by sourceware.org (Postfix) with ESMTPS id 89D2238582B0 for ; Tue, 10 Oct 2023 04:13:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 89D2238582B0 Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=sifive.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=sifive.com Received: by mail-pl1-x633.google.com with SMTP id d9443c01a7336-1c5bf7871dcso37976935ad.1 for ; Mon, 09 Oct 2023 21:13:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1696911196; x=1697515996; darn=gcc.gnu.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=fazDJXEwSYluJiExSRlzb6kdznCAvsQHGliKZlk3pY8=; b=DzkVz+iCCq56n1MmAwzuhP4oOvrWPSeZc7IA873VkowIdlajSTilfchgy547Wz95T2 DG0dU1hMNujlO1xiRW9/DnldsGIU3O0JSyQ2IEANvinLLGZin7ti67GMT/PVRMVwtGCC eTgZ/4PoGAf1B+kz8Kof80UThrslu6Uqrs9VxxurliKgo5cLl63hjlmRgBgu6N+xRi+m TBYVuz1+I7BQsNF5L6jw40IhMP+DQr08nWNlTrUUqALyQcwR+wzM2S4A7D16GPKDQX2+ 8dUb/56inmppAoX58Yfqs/pPFc8QGgGQT3/8SwryJxvyeklPX1roCwcuOGPEEPCXE4Yg WIjw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696911196; x=1697515996; 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=fazDJXEwSYluJiExSRlzb6kdznCAvsQHGliKZlk3pY8=; b=urfGyLhw4yF/+kv17F9bYSpuZqzNB0fmR1Jn0wee4aNxuAF2vlJ5/+ub8qeKK3wGZg gfLGGVnKIn3DRRpMoxmBD4ert5EUKx7A32XvAwXCGapW64DVS+rpRvGbwq7Ko9gDVPzq dJEjN+ZkBk1/FKCPNOfwejIA88kb2KRR4Gkt+XgJJaITOkIfvlCXLwnRMtsoLtazAo/H cJOCamDxcGANfH3KYONVeebCMKHHDas2WkPDlmotOqLe2VoZHc6eeGwMqF6hUOAEGhkR BTdBzIAaZDeqeZMuTgPJ7sngzy9O9qGrl1AyQDJGCOwr3SLNXy75nw22caIm1CvrdYcS LcJA== X-Gm-Message-State: AOJu0Ywmyy0BGjN8jcnL5FLL4fEHYhJFblwC0fE7BijgfQ6DoJMC2/bI eKS4prldVgMC0hIv1BM7xmnizcEL6mDa5IBLBSRKhBXdHUA6d2btphr2MRjJG2TaDI800STRc4k LSFRIdZiTtmwekTg0k371JT9JwakzkjAOb3KpIRm/5ysOmEf7ovY8abZHjhxoElb+ztHBO23n5A rYEUZojA== X-Google-Smtp-Source: AGHT+IH7RWJcpXC2vLYSIvjp3gHY99rSHSMiDCQL2PxLPA1ViexVwmBObOBSqIvZAMcSbkmEuotgXw== X-Received: by 2002:a17:903:54d:b0:1c6:1206:c5b0 with SMTP id jo13-20020a170903054d00b001c61206c5b0mr12712770plb.67.1696911195891; Mon, 09 Oct 2023 21:13:15 -0700 (PDT) Received: from SiX1E.. ([12.44.202.61]) by smtp.gmail.com with ESMTPSA id f12-20020a170902ab8c00b001c444106bcasm10501093plr.46.2023.10.09.21.13.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Oct 2023 21:13:15 -0700 (PDT) From: Kito Cheng To: gcc-patches@gcc.gnu.org, kito.cheng@gmail.com, palmer@dabbelt.com, jeffreyalaw@gmail.com, rdapp@ventanamicro.com, juzhe.zhong@rivai.ai Cc: Kito Cheng Subject: [PATCH v2 3/4] RISC-V: Extend riscv_subset_list, preparatory for target attribute support Date: Mon, 9 Oct 2023 21:13:04 -0700 Message-Id: <20231010041305.9111-4-kito.cheng@sifive.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231010041305.9111-1-kito.cheng@sifive.com> References: <20231010041305.9111-1-kito.cheng@sifive.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.6 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.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org riscv_subset_list only accept a full arch string before, but we need to parse single extension when supporting target attribute, also we may set a riscv_subset_list directly rather than re-parsing the ISA string again. gcc/ChangeLog: * config/riscv/riscv-subset.h (riscv_subset_list::parse_single_std_ext): New. (riscv_subset_list::parse_single_multiletter_ext): Ditto. (riscv_subset_list::clone): Ditto. (riscv_subset_list::parse_single_ext): Ditto. (riscv_subset_list::set_loc): Ditto. (riscv_set_arch_by_subset_list): Ditto. * common/config/riscv/riscv-common.cc (riscv_subset_list::parse_single_std_ext): New. (riscv_subset_list::parse_single_multiletter_ext): Ditto. (riscv_subset_list::clone): Ditto. (riscv_subset_list::parse_single_ext): Ditto. (riscv_subset_list::set_loc): Ditto. (riscv_set_arch_by_subset_list): Ditto. --- gcc/common/config/riscv/riscv-common.cc | 203 ++++++++++++++++++++++++ gcc/config/riscv/riscv-subset.h | 11 ++ 2 files changed, 214 insertions(+) diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index 9a0a68fe5db..25630d5923e 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -1036,6 +1036,41 @@ riscv_subset_list::parse_std_ext (const char *p) return p; } +/* Parsing function for one standard extensions. + + Return Value: + Points to the end of extensions. + + Arguments: + `p`: Current parsing position. */ + +const char * +riscv_subset_list::parse_single_std_ext (const char *p) +{ + if (*p == 'x' || *p == 's' || *p == 'z') + { + error_at (m_loc, + "%<-march=%s%>: Not single-letter extension. " + "%<%c%>", + m_arch, *p); + return nullptr; + } + + unsigned major_version = 0; + unsigned minor_version = 0; + bool explicit_version_p = false; + char subset[2] = {0, 0}; + + subset[0] = *p; + + p++; + + p = parsing_subset_version (subset, p, &major_version, &minor_version, + /* std_ext_p= */ true, &explicit_version_p); + + add (subset, major_version, minor_version, explicit_version_p, false); + return p; +} /* Check any implied extensions for EXT. */ void @@ -1138,6 +1173,102 @@ riscv_subset_list::handle_combine_ext () } } +/* Parsing function for multi-letter extensions. + + Return Value: + Points to the end of extensions. + + Arguments: + `p`: Current parsing position. + `ext_type`: What kind of extensions, 's', 'z' or 'x'. + `ext_type_str`: Full name for kind of extension. */ + + +const char * +riscv_subset_list::parse_single_multiletter_ext (const char *p, + const char *ext_type, + const char *ext_type_str) +{ + unsigned major_version = 0; + unsigned minor_version = 0; + size_t ext_type_len = strlen (ext_type); + + if (strncmp (p, ext_type, ext_type_len) != 0) + return NULL; + + char *subset = xstrdup (p); + const char *end_of_version; + bool explicit_version_p = false; + char *ext; + char backup; + size_t len = strlen (p); + size_t end_of_version_pos, i; + bool found_any_number = false; + bool found_minor_version = false; + + end_of_version_pos = len; + /* Find the begin of version string. */ + for (i = len -1; i > 0; --i) + { + if (ISDIGIT (subset[i])) + { + found_any_number = true; + continue; + } + /* Might be version seperator, but need to check one more char, + we only allow p, so we could stop parsing if found + any more `p`. */ + if (subset[i] == 'p' && + !found_minor_version && + found_any_number && ISDIGIT (subset[i-1])) + { + found_minor_version = true; + continue; + } + + end_of_version_pos = i + 1; + break; + } + + backup = subset[end_of_version_pos]; + subset[end_of_version_pos] = '\0'; + ext = xstrdup (subset); + subset[end_of_version_pos] = backup; + + end_of_version + = parsing_subset_version (ext, subset + end_of_version_pos, &major_version, + &minor_version, /* std_ext_p= */ false, + &explicit_version_p); + free (ext); + + if (end_of_version == NULL) + return NULL; + + subset[end_of_version_pos] = '\0'; + + if (strlen (subset) == 1) + { + error_at (m_loc, "%<-march=%s%>: name of %s must be more than 1 letter", + m_arch, ext_type_str); + free (subset); + return NULL; + } + + add (subset, major_version, minor_version, explicit_version_p, false); + p += end_of_version - subset; + free (subset); + + if (*p != '\0' && *p != '_') + { + error_at (m_loc, "%<-march=%s%>: %s must separate with %<_%>", + m_arch, ext_type_str); + return NULL; + } + + return p; + +} + /* Parsing function for multi-letter extensions. Return Value: @@ -1250,6 +1381,30 @@ riscv_subset_list::parse_multiletter_ext (const char *p, return p; } +/* Parsing function for a single-letter or multi-letter extensions. + + Return Value: + Points to the end of extensions. + + Arguments: + `p`: Current parsing position. */ + +const char * +riscv_subset_list::parse_single_ext (const char *p) +{ + switch (p[0]) + { + case 'x': + return parse_single_multiletter_ext (p, "x", "non-standard extension"); + case 'z': + return parse_single_multiletter_ext (p, "z", "sub-extension"); + case 's': + return parse_single_multiletter_ext (p, "s", "supervisor extension"); + default: + return parse_single_std_ext (p); + } +} + /* Parsing arch string to subset list, return NULL if parsing failed. */ riscv_subset_list * @@ -1342,6 +1497,26 @@ fail: return NULL; } +/* Clone whole subset list. */ + +riscv_subset_list * +riscv_subset_list::clone () const +{ + riscv_subset_list *new_list = new riscv_subset_list (m_arch, m_loc); + for (riscv_subset_t *itr = m_head; itr != NULL; itr = itr->next) + new_list->add (itr->name.c_str (), itr->major_version, itr->minor_version, + itr->explicit_version_p, true); + + new_list->m_xlen = m_xlen; + return new_list; +} + +void +riscv_subset_list::set_loc (location_t loc) +{ + m_loc = loc; +} + /* Return the current arch string. */ std::string @@ -1498,6 +1673,34 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] = {NULL, NULL, 0} }; +void +riscv_set_arch_by_subset_list (riscv_subset_list *subset_list, + struct gcc_options *opts) +{ + if (opts) + { + const riscv_ext_flag_table_t *arch_ext_flag_tab; + /* Clean up target flags before we set. */ + for (arch_ext_flag_tab = &riscv_ext_flag_table[0]; arch_ext_flag_tab->ext; + ++arch_ext_flag_tab) + opts->*arch_ext_flag_tab->var_ref &= ~arch_ext_flag_tab->mask; + + if (subset_list->xlen () == 32) + opts->x_target_flags &= ~MASK_64BIT; + else if (subset_list->xlen () == 64) + opts->x_target_flags |= MASK_64BIT; + + for (arch_ext_flag_tab = &riscv_ext_flag_table[0]; arch_ext_flag_tab->ext; + ++arch_ext_flag_tab) + { + if (subset_list->lookup (arch_ext_flag_tab->ext)) + opts->*arch_ext_flag_tab->var_ref |= arch_ext_flag_tab->mask; + } + } + + current_subset_list = subset_list; +} + /* Parse a RISC-V ISA string into an option mask. Must clear or set all arch dependent mask bits, in case more than one -march string is passed. */ diff --git a/gcc/config/riscv/riscv-subset.h b/gcc/config/riscv/riscv-subset.h index dca07284efa..d2a4bd20530 100644 --- a/gcc/config/riscv/riscv-subset.h +++ b/gcc/config/riscv/riscv-subset.h @@ -69,8 +69,12 @@ private: const char *parse_std_ext (const char *); + const char *parse_single_std_ext (const char *); + const char *parse_multiletter_ext (const char *, const char *, const char *); + const char *parse_single_multiletter_ext (const char *, const char *, + const char *); void handle_implied_ext (const char *); bool check_implied_ext (); @@ -91,14 +95,21 @@ public: unsigned xlen () const {return m_xlen;}; + riscv_subset_list *clone () const; + static riscv_subset_list *parse (const char *, location_t); + const char *parse_single_ext (const char *); const riscv_subset_t *begin () const {return m_head;}; const riscv_subset_t *end () const {return NULL;}; int match_score (riscv_subset_list *) const; + + void set_loc (location_t); }; extern const riscv_subset_list *riscv_current_subset_list (void); +extern void +riscv_set_arch_by_subset_list (riscv_subset_list *, struct gcc_options *); #endif /* ! GCC_RISCV_SUBSET_H */