From patchwork Sat Mar 30 08:43:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yang Yujie X-Patchwork-Id: 1918074 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; 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 [8.43.85.97]) (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 4V6FFS4mwBz1yWv for ; Sat, 30 Mar 2024 22:20:42 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A96113858D33 for ; Sat, 30 Mar 2024 11:20:40 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from eggs.gnu.org (eggs.gnu.org [IPv6:2001:470:142:3::10]) by sourceware.org (Postfix) with ESMTPS id 90B4E3858D1E for ; Sat, 30 Mar 2024 11:20:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 90B4E3858D1E Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=loongson.cn ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 90B4E3858D1E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2001:470:142:3::10 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1711797623; cv=none; b=tPqmHzPKcZqxMezqPJV56UtF3waNeHlvI85R/aHpJoa8dChjDg3fJtc+8mxUmPz3W1SUMl7xf5/1wO7fXoO4Oa/pXcZpW9vgDsfVxXcExj50QsOii1d8XMOm3QiyY+/67XLvYohhKCS9pK+8xqCRkmV6ASEmGDM9TXvmL/htuy8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1711797623; c=relaxed/simple; bh=rQxBbemI/eQFvdjsVNzFtqPgWTVeuoC4Spy5oPsxHbE=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=CrvdcgqXgTX/uOfiNjSFMRk7symunxpgFuI6zc9z8I3+tmbCChkYSk5uYYDV79J74DUl6u5Y6JHTQMkK5Am8RYR+69SnmVsJ6T8tEEBuzhvCgEoo1sKA20MlPP5KA83fI8bsrwXNZG+j/b2hC8WUEuJo1qJDV8Rn3zAJT3lq04I= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from mail.loongson.cn ([114.242.206.163]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rqV3L-00008N-EB for gcc-patches@gcc.gnu.org; Sat, 30 Mar 2024 05:31:11 -0400 Received: from loongson.cn (unknown [114.243.97.77]) by gateway (Coremail) with SMTP id _____8AxuujN2wdmmU0hAA--.56886S3; Sat, 30 Mar 2024 17:30:54 +0800 (CST) Received: from localhost.localdomain (unknown [114.243.97.77]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Bxb8_K2wdmRIpuAA--.15918S2; Sat, 30 Mar 2024 17:30:50 +0800 (CST) From: Yang Yujie To: gcc-patches@gcc.gnu.org Cc: chenglulu@loongson.cn, xuchenghua@loongson.cn, Yang Yujie Subject: [PATCH v4] LoongArch: Split loongarch_option_override_internal into smaller procedures Date: Sat, 30 Mar 2024 16:43:14 +0800 Message-ID: <20240330084313.827920-2-yangyujie@loongson.cn> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 X-CM-TRANSID: AQAAf8Bxb8_K2wdmRIpuAA--.15918S2 X-CM-SenderInfo: 51dqw5pxmlvqxorr0wxvrqhubq/1tbiAQALAGYFKmkNyQA2sY X-Coremail-Antispam: 1Uk129KBj9fXoWfZw4DuFW5KF17WFWfGw1Dtwc_yoW5JFy8uo W3AFWkXr18Gr1F93yrtwnagrWjqF1UAr47Aa47uw1fWFn7Zr15Jry3Kw1Yva43ArsxXrW5 CasFg3ZrZFyxJFn3l-sFpf9Il3svdjkaLaAFLSUrUUUUUb8apTn2vfkv8UJUUUU8wcxFpf 9Il3svdxBIdaVrn0xqx4xG64xvF2IEw4CE5I8CrVC2j2Jv73VFW2AGmfu7bjvjm3AaLaJ3 UjIYCTnIWjp_UUUYU7kC6x804xWl14x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI 8IcIk0rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xG Y2AK021l84ACjcxK6xIIjxv20xvE14v26r1j6r1xM28EF7xvwVC0I7IYx2IY6xkF7I0E14 v26r1j6r4UM28EF7xvwVC2z280aVAFwI0_Gr0_Cr1l84ACjcxK6I8E87Iv6xkF7I0E14v2 6r4j6r4UJwAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07AIYIkI8VC2zVCFFI0UMc 02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWUJVWUGwAv7VC2z280aVAF wI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JMxAIw28IcxkI7V AKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCj r7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42IY6x IIjxv20xvE14v26r1j6r1xMIIF0xvE2Ix0cI8IcVCY1x0267AKxVWUJVW8JwCI42IY6xAI w20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x 0267AKxVWUJVW8JbIYCTnIWIevJa73UjIFyTuYvjxUzsqWUUUUU Received-SPF: pass client-ip=114.242.206.163; envelope-from=yangyujie@loongson.cn; helo=mail.loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_FAIL, SPF_HELO_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 gcc/ChangeLog: * config/loongarch/genopts/loongarch.opt.in: Mark -m[no-]recip as aliases to -mrecip={all,none}, respectively. * config/loongarch/loongarch.opt: Regenerate. * config/loongarch/loongarch-def.h (ABI_FPU_64): Rename to... (ABI_FPU64_P): ...this. (ABI_FPU_32): Rename to... (ABI_FPU32_P): ...this. (ABI_FPU_NONE): Rename to... (ABI_NOFPU_P): ...this. (ABI_LP64_P): Define. * config/loongarch/loongarch.cc (loongarch_init_print_operand_punct): Merged into loongarch_global_init. (loongarch_cpu_option_override): Renamed to loongarch_target_option_override. (loongarch_option_override_internal): Move the work after loongarch_config_target into loongarch_target_option_override. (loongarch_global_init): Define. (INIT_TARGET_FLAG): Move to loongarch-opts.cc. (loongarch_option_override): Call loongarch_global_init separately. * config/loongarch/loongarch-opts.cc (loongarch_parse_mrecip_scheme): Split the parsing of -mrecip= from loongarch_option_override_internal. (loongarch_generate_mrecip_scheme): Define. Split from loongarch_option_override_internal. (loongarch_target_option_override): Define. Renamed from loongarch_cpu_option_override. (loongarch_init_misc_options): Define. Split from loongarch_option_override_internal. (INIT_TARGET_FLAG): Move from loongarch.cc. * config/loongarch/loongarch-opts.h (loongarch_target_option_override): New prototype. (loongarch_parse_mrecip_scheme): New prototype. (loongarch_init_misc_options): New prototype. (TARGET_ABI_LP64): Simplify with ABI_LP64_P. * config/loongarch/loongarch.h (TARGET_RECIP_DIV): Simplify. Do not reference specific CPU architecture (LA664). (TARGET_RECIP_SQRT): Same. (TARGET_RECIP_RSQRT): Same. (TARGET_RECIP_VEC_DIV): Same. (TARGET_RECIP_VEC_SQRT): Same. (TARGET_RECIP_VEC_RSQRT): Same. --- gcc/config/loongarch/genopts/loongarch.opt.in | 8 +- gcc/config/loongarch/loongarch-def.h | 11 +- gcc/config/loongarch/loongarch-opts.cc | 253 ++++++++++++++++++ gcc/config/loongarch/loongarch-opts.h | 27 +- gcc/config/loongarch/loongarch.cc | 253 +++--------------- gcc/config/loongarch/loongarch.h | 18 +- gcc/config/loongarch/loongarch.opt | 8 +- 7 files changed, 342 insertions(+), 236 deletions(-) diff --git a/gcc/config/loongarch/genopts/loongarch.opt.in b/gcc/config/loongarch/genopts/loongarch.opt.in index 02f918053f5..a77893d31d9 100644 --- a/gcc/config/loongarch/genopts/loongarch.opt.in +++ b/gcc/config/loongarch/genopts/loongarch.opt.in @@ -197,14 +197,14 @@ mexplicit-relocs Target Alias(mexplicit-relocs=, always, none) Use %reloc() assembly operators (for backward compatibility). -mrecip -Target RejectNegative Var(la_recip) Save -Generate approximate reciprocal divide and square root for better throughput. - mrecip= Target RejectNegative Joined Var(la_recip_name) Save Control generation of reciprocal estimates. +mrecip +Target Alias(mrecip=, all, none) +Generate approximate reciprocal divide and square root for better throughput. + ; The code model option names for -mcmodel. Enum Name(cmodel) Type(int) diff --git a/gcc/config/loongarch/loongarch-def.h b/gcc/config/loongarch/loongarch-def.h index 2dbf006d013..0cbf9476690 100644 --- a/gcc/config/loongarch/loongarch-def.h +++ b/gcc/config/loongarch/loongarch-def.h @@ -90,11 +90,16 @@ extern loongarch_def_array #define TO_LP64_ABI_BASE(C) (C) -#define ABI_FPU_64(abi_base) \ +#define ABI_LP64_P(abi_base) \ + (abi_base == ABI_BASE_LP64D \ + || abi_base == ABI_BASE_LP64F \ + || abi_base == ABI_BASE_LP64S) + +#define ABI_FPU64_P(abi_base) \ (abi_base == ABI_BASE_LP64D) -#define ABI_FPU_32(abi_base) \ +#define ABI_FPU32_P(abi_base) \ (abi_base == ABI_BASE_LP64F) -#define ABI_FPU_NONE(abi_base) \ +#define ABI_NOFPU_P(abi_base) \ (abi_base == ABI_BASE_LP64S) diff --git a/gcc/config/loongarch/loongarch-opts.cc b/gcc/config/loongarch/loongarch-opts.cc index 627f9148adf..e600f08f03b 100644 --- a/gcc/config/loongarch/loongarch-opts.cc +++ b/gcc/config/loongarch/loongarch-opts.cc @@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tm.h" #include "obstack.h" +#include "opts.h" #include "diagnostic-core.h" #include "loongarch-cpu.h" @@ -32,8 +33,12 @@ along with GCC; see the file COPYING3. If not see #include "loongarch-str.h" #include "loongarch-def.h" +/* Target configuration */ struct loongarch_target la_target; +/* RTL cost information */ +const struct loongarch_rtx_cost_data *loongarch_cost; + /* ABI-related configuration. */ #define ABI_COUNT (sizeof(abi_priority_list)/sizeof(struct loongarch_abi)) static const struct loongarch_abi @@ -795,3 +800,251 @@ loongarch_update_gcc_opt_status (struct loongarch_target *target, /* ISA evolution features */ opts->x_la_isa_evolution = target->isa.evolution; } + +/* -mrecip= handling */ +static struct + { + const char *string; /* option name. */ + unsigned int mask; /* mask bits to set. */ + } +const recip_options[] = { + { "all", RECIP_MASK_ALL }, + { "none", RECIP_MASK_NONE }, + { "div", RECIP_MASK_DIV }, + { "sqrt", RECIP_MASK_SQRT }, + { "rsqrt", RECIP_MASK_RSQRT }, + { "vec-div", RECIP_MASK_VEC_DIV }, + { "vec-sqrt", RECIP_MASK_VEC_SQRT }, + { "vec-rsqrt", RECIP_MASK_VEC_RSQRT }, +}; + +/* Parser for -mrecip=. */ +unsigned int +loongarch_parse_mrecip_scheme (const char *recip_string) +{ + unsigned int result_mask = RECIP_MASK_NONE; + + if (recip_string) + { + char *p = ASTRDUP (recip_string); + char *q; + unsigned int mask, i; + bool invert; + + while ((q = strtok (p, ",")) != NULL) + { + p = NULL; + if (*q == '!') + { + invert = true; + q++; + } + else + invert = false; + + if (!strcmp (q, "default")) + mask = RECIP_MASK_ALL; + else + { + for (i = 0; i < ARRAY_SIZE (recip_options); i++) + if (!strcmp (q, recip_options[i].string)) + { + mask = recip_options[i].mask; + break; + } + + if (i == ARRAY_SIZE (recip_options)) + { + error ("unknown option for %<-mrecip=%s%>", q); + invert = false; + mask = RECIP_MASK_NONE; + } + } + + if (invert) + result_mask &= ~mask; + else + result_mask |= mask; + } + } + return result_mask; +} + +/* Generate -mrecip= argument based on the mask. */ +const char* +loongarch_generate_mrecip_scheme (unsigned int mask) +{ + static char recip_scheme_str[128]; + int p = 0, tmp; + + switch (mask) + { + case RECIP_MASK_ALL: + return "all"; + + case RECIP_MASK_NONE: + return "none"; + } + + for (unsigned long i = 2; i < ARRAY_SIZE (recip_options); i++) + { + if (mask & recip_options[i].mask) + { + if ((tmp = strlen (recip_options[i].string) + 1) >= 127 - p) + gcc_unreachable (); + + recip_scheme_str[p] = ','; + strcpy (recip_scheme_str + p + 1, recip_options[i].string); + p += tmp; + } + } + recip_scheme_str[p] = '\0'; + return recip_scheme_str + 1; +} + + + +/* Refresh the switches acccording to the resolved loongarch_target struct. */ +void +loongarch_target_option_override (struct loongarch_target *target, + struct gcc_options *opts, + struct gcc_options *opts_set) +{ + loongarch_update_gcc_opt_status (target, opts, opts_set); + + /* alignments */ + if (opts->x_flag_align_functions && !opts->x_str_align_functions) + opts->x_str_align_functions + = loongarch_cpu_align[target->cpu_tune].function; + + if (opts->x_flag_align_labels && !opts->x_str_align_labels) + opts->x_str_align_labels = loongarch_cpu_align[target->cpu_tune].label; + + /* Set up parameters to be used in prefetching algorithm. */ + int simultaneous_prefetches + = loongarch_cpu_cache[target->cpu_tune].simultaneous_prefetches; + + SET_OPTION_IF_UNSET (opts, opts_set, param_simultaneous_prefetches, + simultaneous_prefetches); + + SET_OPTION_IF_UNSET (opts, opts_set, param_l1_cache_line_size, + loongarch_cpu_cache[target->cpu_tune].l1d_line_size); + + SET_OPTION_IF_UNSET (opts, opts_set, param_l1_cache_size, + loongarch_cpu_cache[target->cpu_tune].l1d_size); + + SET_OPTION_IF_UNSET (opts, opts_set, param_l2_cache_size, + loongarch_cpu_cache[target->cpu_tune].l2d_size); + + /* Other arch-specific overrides. */ + switch (target->cpu_arch) + { + case CPU_LA664: + /* Enable -mrecipe=all for LA664 by default. */ + if (!opts_set->x_recip_mask) + { + opts->x_recip_mask = RECIP_MASK_ALL; + opts_set->x_recip_mask = 1; + } + } + + /* -mrecip= */ + opts->x_la_recip_name + = loongarch_generate_mrecip_scheme (opts->x_recip_mask); + + /* Decide which rtx_costs structure to use. */ + if (opts->x_optimize_size) + loongarch_cost = &loongarch_rtx_cost_optimize_size; + else + loongarch_cost = &loongarch_cpu_rtx_cost_data[target->cpu_tune]; + + /* If the user hasn't specified a branch cost, use the processor's + default. */ + if (!opts_set->x_la_branch_cost) + opts->x_la_branch_cost = loongarch_cost->branch_cost; + + /* other stuff */ + if (ABI_LP64_P (target->abi.base)) + opts->x_flag_pcc_struct_return = 0; + + switch (target->cmodel) + { + case CMODEL_EXTREME: + if (opts->x_flag_plt) + { + if (opts_set->x_flag_plt) + error ("code model %qs is not compatible with %s", + "extreme", "-fplt"); + opts->x_flag_plt = 0; + } + break; + + case CMODEL_TINY_STATIC: + case CMODEL_MEDIUM: + case CMODEL_NORMAL: + case CMODEL_TINY: + case CMODEL_LARGE: + break; + + default: + gcc_unreachable (); + } +} + + +/* Resolve options that's not covered by la_target. */ +void +loongarch_init_misc_options (struct gcc_options *opts, + struct gcc_options *opts_set) +{ + if (opts->x_flag_pic) + opts->x_g_switch_value = 0; + + /* -mrecip options. */ + opts->x_recip_mask = loongarch_parse_mrecip_scheme (opts->x_la_recip_name); + +#define INIT_TARGET_FLAG(NAME, INIT) \ + { \ + if (!(opts_set->x_target_flags & MASK_##NAME)) \ + { \ + if (INIT) \ + opts->x_target_flags |= MASK_##NAME; \ + else \ + opts->x_target_flags &= ~MASK_##NAME; \ + } \ + } + + /* Enable conditional moves for int and float by default. */ + INIT_TARGET_FLAG (COND_MOVE_INT, 1) + INIT_TARGET_FLAG (COND_MOVE_FLOAT, 1) + + /* Set mrelax default. */ + INIT_TARGET_FLAG (LINKER_RELAXATION, + HAVE_AS_MRELAX_OPTION && HAVE_AS_COND_BRANCH_RELAXATION) + +#undef INIT_TARGET_FLAG + + /* Set mexplicit-relocs default. */ + if (opts->x_la_opt_explicit_relocs == M_OPT_UNSET) + opts->x_la_opt_explicit_relocs = (HAVE_AS_EXPLICIT_RELOCS + ? (TARGET_LINKER_RELAXATION + ? EXPLICIT_RELOCS_AUTO + : EXPLICIT_RELOCS_ALWAYS) + : EXPLICIT_RELOCS_NONE); + + /* Enable sw prefetching at -O3 and higher. */ + if (opts->x_flag_prefetch_loop_arrays < 0 + && (opts->x_optimize >= 3 || opts->x_flag_profile_use) + && !opts->x_optimize_size) + opts->x_flag_prefetch_loop_arrays = 1; + + if (TARGET_DIRECT_EXTERN_ACCESS_OPTS_P (opts) && opts->x_flag_shlib) + error ("%qs cannot be used for compiling a shared library", + "-mdirect-extern-access"); + + /* Enforce that interval is the same size as size so the mid-end does the + right thing. */ + SET_OPTION_IF_UNSET (opts, opts_set, + param_stack_clash_protection_probe_interval, + param_stack_clash_protection_guard_size); +} diff --git a/gcc/config/loongarch/loongarch-opts.h b/gcc/config/loongarch/loongarch-opts.h index 586e67e65ee..2d9f59296e7 100644 --- a/gcc/config/loongarch/loongarch-opts.h +++ b/gcc/config/loongarch/loongarch-opts.h @@ -30,6 +30,10 @@ along with GCC; see the file COPYING3. If not see /* Target configuration */ extern struct loongarch_target la_target; +/* RTL cost information */ +extern const struct loongarch_rtx_cost_data *loongarch_cost; + + /* Initialize loongarch_target from separate option variables. */ void loongarch_init_target (struct loongarch_target *target, @@ -46,11 +50,30 @@ loongarch_config_target (struct loongarch_target *target, struct loongarch_flags *flags, int follow_multilib_list_p); + +/* Refresh the switches acccording to the resolved loongarch_target struct. */ +void +loongarch_target_option_override (struct loongarch_target *target, + struct gcc_options *opts, + struct gcc_options *opts_set); + + /* option status feedback for "gcc --help=target -Q" */ void loongarch_update_gcc_opt_status (struct loongarch_target *target, struct gcc_options *opts, struct gcc_options *opts_set); + + +/* Parser for -mrecip=. */ +unsigned int +loongarch_parse_mrecip_scheme (const char *recip_string); + + +/* Resolve options that's not covered by la_target. */ +void +loongarch_init_misc_options (struct gcc_options *opts, + struct gcc_options *opts_set); #endif /* Flag status */ @@ -80,9 +103,7 @@ struct loongarch_flags { #define TARGET_DOUBLE_FLOAT_ABI (la_target.abi.base == ABI_BASE_LP64D) #define TARGET_64BIT (la_target.isa.base == ISA_BASE_LA64) -#define TARGET_ABI_LP64 (la_target.abi.base == ABI_BASE_LP64D \ - || la_target.abi.base == ABI_BASE_LP64F \ - || la_target.abi.base == ABI_BASE_LP64S) +#define TARGET_ABI_LP64 ABI_LP64_P(la_target.abi.base) #define ISA_HAS_LSX \ (la_target.isa.simd == ISA_EXT_SIMD_LSX \ diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index 030957db4e7..a69a203fbe6 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -208,9 +208,6 @@ const enum reg_class loongarch_regno_to_class[FIRST_PSEUDO_REGISTER] = { FRAME_REGS, FRAME_REGS }; -/* Which cost information to use. */ -static const struct loongarch_rtx_cost_data *loongarch_cost; - /* Information about a single argument. */ struct loongarch_arg_info { @@ -5911,17 +5908,6 @@ loongarch_print_operand_punctuation (FILE *file, int ch) } } -/* Initialize loongarch_print_operand_punct. */ - -static void -loongarch_init_print_operand_punct (void) -{ - const char *p; - - for (p = ".$"; *p; p++) - loongarch_print_operand_punct[(unsigned char) *p] = true; -} - /* PRINT_OPERAND prefix LETTER refers to the integer branch instruction associated with condition CODE. Print the condition part of the opcode to FILE. */ @@ -7625,118 +7611,15 @@ loongarch_init_machine_status (void) } static void -loongarch_cpu_option_override (struct loongarch_target *target, - struct gcc_options *opts, - struct gcc_options *opts_set) -{ - /* alignments */ - if (opts->x_flag_align_functions && !opts->x_str_align_functions) - opts->x_str_align_functions - = loongarch_cpu_align[target->cpu_tune].function; - - if (opts->x_flag_align_labels && !opts->x_str_align_labels) - opts->x_str_align_labels = loongarch_cpu_align[target->cpu_tune].label; - - /* Set up parameters to be used in prefetching algorithm. */ - int simultaneous_prefetches - = loongarch_cpu_cache[target->cpu_tune].simultaneous_prefetches; - - SET_OPTION_IF_UNSET (opts, opts_set, param_simultaneous_prefetches, - simultaneous_prefetches); - - SET_OPTION_IF_UNSET (opts, opts_set, param_l1_cache_line_size, - loongarch_cpu_cache[target->cpu_tune].l1d_line_size); - - SET_OPTION_IF_UNSET (opts, opts_set, param_l1_cache_size, - loongarch_cpu_cache[target->cpu_tune].l1d_size); - - SET_OPTION_IF_UNSET (opts, opts_set, param_l2_cache_size, - loongarch_cpu_cache[target->cpu_tune].l2d_size); -} - -static void -loongarch_option_override_internal (struct gcc_options *opts, - struct gcc_options *opts_set) +loongarch_global_init (void) { - int i, regno, mode; - - if (flag_pic) - g_switch_value = 0; - - loongarch_init_target (&la_target, - la_opt_cpu_arch, la_opt_cpu_tune, la_opt_fpu, - la_opt_simd, la_opt_abi_base, la_opt_abi_ext, - la_opt_cmodel, opts->x_la_isa_evolution, - opts_set->x_la_isa_evolution); - - /* Handle target-specific options: compute defaults/conflicts etc. */ - loongarch_config_target (&la_target, NULL, 0); - - loongarch_update_gcc_opt_status (&la_target, opts, opts_set); - loongarch_cpu_option_override (&la_target, opts, opts_set); - - if (TARGET_ABI_LP64) - flag_pcc_struct_return = 0; - - /* Decide which rtx_costs structure to use. */ - if (optimize_size) - loongarch_cost = &loongarch_rtx_cost_optimize_size; - else - loongarch_cost = &loongarch_cpu_rtx_cost_data[la_target.cpu_tune]; - - /* If the user hasn't specified a branch cost, use the processor's - default. */ - if (la_branch_cost == 0) - la_branch_cost = loongarch_cost->branch_cost; - - /* Enable sw prefetching at -O3 and higher. */ - if (opts->x_flag_prefetch_loop_arrays < 0 - && (opts->x_optimize >= 3 || opts->x_flag_profile_use) - && !opts->x_optimize_size) - opts->x_flag_prefetch_loop_arrays = 1; - - if (TARGET_DIRECT_EXTERN_ACCESS && flag_shlib) - error ("%qs cannot be used for compiling a shared library", - "-mdirect-extern-access"); - - switch (la_target.cmodel) - { - case CMODEL_EXTREME: - if (opts->x_flag_plt) - { - if (global_options_set.x_flag_plt) - error ("code model %qs is not compatible with %s", - "extreme", "-fplt"); - opts->x_flag_plt = 0; - } - break; - - case CMODEL_TINY_STATIC: - case CMODEL_MEDIUM: - case CMODEL_NORMAL: - case CMODEL_TINY: - case CMODEL_LARGE: - break; - - default: - gcc_unreachable (); - } - - /* Validate the guard size. */ - int guard_size = param_stack_clash_protection_guard_size; - - /* Enforce that interval is the same size as size so the mid-end does the - right thing. */ - SET_OPTION_IF_UNSET (opts, &global_options_set, - param_stack_clash_protection_probe_interval, - guard_size); - - loongarch_init_print_operand_punct (); + /* Initialize loongarch_print_operand_punct. */ + for (const char *p = ".$"; *p; p++) + loongarch_print_operand_punct[(unsigned char) *p] = true; /* Set up array to map GCC register number to debug register number. Ignore the special purpose register numbers. */ - - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) + for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++) { if (GP_REG_P (i) || FP_REG_P (i)) loongarch_dwarf_regno[i] = i; @@ -7745,115 +7628,53 @@ loongarch_option_override_internal (struct gcc_options *opts, } /* Set up loongarch_hard_regno_mode_ok. */ - for (mode = 0; mode < MAX_MACHINE_MODE; mode++) - for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + for (int mode = 0; mode < MAX_MACHINE_MODE; mode++) + for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) loongarch_hard_regno_mode_ok_p[mode][regno] = loongarch_hard_regno_mode_ok_uncached (regno, (machine_mode) mode); /* Function to allocate machine-dependent function status. */ init_machine_status = &loongarch_init_machine_status; +}; - /* -mrecip options. */ - static struct - { - const char *string; /* option name. */ - unsigned int mask; /* mask bits to set. */ - } - const recip_options[] = { - { "all", RECIP_MASK_ALL }, - { "none", RECIP_MASK_NONE }, - { "div", RECIP_MASK_DIV }, - { "sqrt", RECIP_MASK_SQRT }, - { "rsqrt", RECIP_MASK_RSQRT }, - { "vec-div", RECIP_MASK_VEC_DIV }, - { "vec-sqrt", RECIP_MASK_VEC_SQRT }, - { "vec-rsqrt", RECIP_MASK_VEC_RSQRT }, - }; - - if (la_recip_name) - { - char *p = ASTRDUP (la_recip_name); - char *q; - unsigned int mask, i; - bool invert; - - while ((q = strtok (p, ",")) != NULL) - { - p = NULL; - if (*q == '!') - { - invert = true; - q++; - } - else - invert = false; - - if (!strcmp (q, "default")) - mask = RECIP_MASK_ALL; - else - { - for (i = 0; i < ARRAY_SIZE (recip_options); i++) - if (!strcmp (q, recip_options[i].string)) - { - mask = recip_options[i].mask; - break; - } - - if (i == ARRAY_SIZE (recip_options)) - { - error ("unknown option for %<-mrecip=%s%>", q); - invert = false; - mask = RECIP_MASK_NONE; - } - } - - if (invert) - recip_mask &= ~mask; - else - recip_mask |= mask; - } - } - if (la_recip) - recip_mask |= RECIP_MASK_ALL; - if (!ISA_HAS_FRECIPE) - recip_mask = RECIP_MASK_NONE; - -#define INIT_TARGET_FLAG(NAME, INIT) \ - { \ - if (!(target_flags_explicit & MASK_##NAME)) \ - { \ - if (INIT) \ - target_flags |= MASK_##NAME; \ - else \ - target_flags &= ~MASK_##NAME; \ - } \ - } - - /* Enable conditional moves for int and float by default. */ - INIT_TARGET_FLAG (COND_MOVE_INT, 1) - INIT_TARGET_FLAG (COND_MOVE_FLOAT, 1) - - /* Set mrelax default. */ - INIT_TARGET_FLAG (LINKER_RELAXATION, - HAVE_AS_MRELAX_OPTION && HAVE_AS_COND_BRANCH_RELAXATION) +static void +loongarch_option_override_internal (struct loongarch_target *target, + struct gcc_options *opts, + struct gcc_options *opts_set) +{ + /* Handle options not covered by struct loongarch_target. */ + loongarch_init_misc_options (opts, opts_set); + + /* Resolve the target struct. */ + loongarch_init_target (target, + opts->x_la_opt_cpu_arch, + opts->x_la_opt_cpu_tune, + opts->x_la_opt_fpu, + opts->x_la_opt_simd, + opts->x_la_opt_abi_base, + opts->x_la_opt_abi_ext, + opts->x_la_opt_cmodel, + opts->x_la_isa_evolution, + opts_set->x_la_isa_evolution); -#undef INIT_TARGET_FLAG + loongarch_config_target (target, NULL, 0); - if (la_opt_explicit_relocs == M_OPT_UNSET) - la_opt_explicit_relocs = (HAVE_AS_EXPLICIT_RELOCS - ? (TARGET_LINKER_RELAXATION - ? EXPLICIT_RELOCS_AUTO - : EXPLICIT_RELOCS_ALWAYS) - : EXPLICIT_RELOCS_NONE); + /* Override some options according to the resolved target. */ + loongarch_target_option_override (target, opts, opts_set); } - /* Implement TARGET_OPTION_OVERRIDE. */ static void loongarch_option_override (void) { - loongarch_option_override_internal (&global_options, &global_options_set); + /* Setting up the target configuration. */ + loongarch_option_override_internal (&la_target, + &global_options, + &global_options_set); + + /* Global initializations. */ + loongarch_global_init (); } /* Implement TARGET_OPTION_SAVE. */ diff --git a/gcc/config/loongarch/loongarch.h b/gcc/config/loongarch/loongarch.h index 888a633961d..23bb3254883 100644 --- a/gcc/config/loongarch/loongarch.h +++ b/gcc/config/loongarch/loongarch.h @@ -710,12 +710,18 @@ enum reg_class | RECIP_MASK_RSQRT | RECIP_MASK_VEC_SQRT \ | RECIP_MASK_VEC_DIV | RECIP_MASK_VEC_RSQRT) -#define TARGET_RECIP_DIV ((recip_mask & RECIP_MASK_DIV) != 0 || TARGET_uARCH_LA664) -#define TARGET_RECIP_SQRT ((recip_mask & RECIP_MASK_SQRT) != 0 || TARGET_uARCH_LA664) -#define TARGET_RECIP_RSQRT ((recip_mask & RECIP_MASK_RSQRT) != 0 || TARGET_uARCH_LA664) -#define TARGET_RECIP_VEC_DIV ((recip_mask & RECIP_MASK_VEC_DIV) != 0 || TARGET_uARCH_LA664) -#define TARGET_RECIP_VEC_SQRT ((recip_mask & RECIP_MASK_VEC_SQRT) != 0 || TARGET_uARCH_LA664) -#define TARGET_RECIP_VEC_RSQRT ((recip_mask & RECIP_MASK_VEC_RSQRT) != 0 || TARGET_uARCH_LA664) +#define TARGET_RECIP_DIV \ + ((recip_mask & RECIP_MASK_DIV) != 0 && ISA_HAS_FRECIPE) +#define TARGET_RECIP_SQRT \ + ((recip_mask & RECIP_MASK_SQRT) != 0 && ISA_HAS_FRECIPE) +#define TARGET_RECIP_RSQRT \ + ((recip_mask & RECIP_MASK_RSQRT) != 0 && ISA_HAS_FRECIPE) +#define TARGET_RECIP_VEC_DIV \ + ((recip_mask & RECIP_MASK_VEC_DIV) != 0 && ISA_HAS_FRECIPE) +#define TARGET_RECIP_VEC_SQRT \ + ((recip_mask & RECIP_MASK_VEC_SQRT) != 0 && ISA_HAS_FRECIPE) +#define TARGET_RECIP_VEC_RSQRT \ + ((recip_mask & RECIP_MASK_VEC_RSQRT) != 0 && ISA_HAS_FRECIPE) /* 1 if N is a possible register number for function argument passing. We have no FP argument registers when soft-float. */ diff --git a/gcc/config/loongarch/loongarch.opt b/gcc/config/loongarch/loongarch.opt index f10fcdd968c..317cd11a67c 100644 --- a/gcc/config/loongarch/loongarch.opt +++ b/gcc/config/loongarch/loongarch.opt @@ -205,14 +205,14 @@ mexplicit-relocs Target Alias(mexplicit-relocs=, always, none) Use %reloc() assembly operators (for backward compatibility). -mrecip -Target RejectNegative Var(la_recip) Save -Generate approximate reciprocal divide and square root for better throughput. - mrecip= Target RejectNegative Joined Var(la_recip_name) Save Control generation of reciprocal estimates. +mrecip +Target Alias(mrecip=, all, none) +Generate approximate reciprocal divide and square root for better throughput. + ; The code model option names for -mcmodel. Enum Name(cmodel) Type(int)