From patchwork Fri Feb 23 06:22:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yang Yujie X-Patchwork-Id: 1903102 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=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 4Th0bG6CRBz23cl for ; Fri, 23 Feb 2024 17:34:01 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 65E783858281 for ; Fri, 23 Feb 2024 06:33:56 +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 3B1E23858CD1 for ; Fri, 23 Feb 2024 06:33:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 3B1E23858CD1 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 3B1E23858CD1 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=1708670018; cv=none; b=anFZTOLBnBu+S80LgHnUbqBpnjEiFGD+VzH0kTD3Ia2GlmNiPYRBAsvlmedtOOPqzFx4rl1Der6C/CGHsiJqQyFXWSuen1W/06IKdW19c+M4cuQvWRkuj1XV92/osFKSs7kWOUlk4UHZtJAhjf/kNK/qM67+tbfWf1F16YQUqrI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708670018; c=relaxed/simple; bh=r+5knbX9eyI9MBWvlhildGWX/2benTE+TkxzvFAHTRo=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=pgUejpjWbsVKbWAz69LVfOCzERsDuAwuWOXlnw/5VSGaTyO0x5TBnAyzZVRWCVUbJu/3r9KPNcVzWCvtXbAZzO93ERgzQ28mKQShEQdy20Q7nXOqmZ4PbVxAT3Z4DNfZ1uj/ofqU1RoK7mavEISH2CdimGhg8awCSoSE/BWePrE= 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 1rdP7a-0001qi-ME for gcc-patches@gcc.gnu.org; Fri, 23 Feb 2024 01:33:31 -0500 Received: from loongson.cn (unknown [114.243.98.62]) by gateway (Coremail) with SMTP id _____8CxWOgkPNhliZEQAA--.23347S3; Fri, 23 Feb 2024 14:33:09 +0800 (CST) Received: from localhost.localdomain (unknown [114.243.98.62]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxzM4iPNhl640_AA--.10922S2; Fri, 23 Feb 2024 14:33:06 +0800 (CST) From: Yang Yujie To: gcc-patches@gcc.gnu.org Cc: chenglulu@loongson.cn, xuchenghua@loongson.cn, Yang Yujie Subject: [PATCH v3] LoongArch: Split loongarch_option_override_internal into smaller procedures Date: Fri, 23 Feb 2024 14:22:02 +0800 Message-ID: <20240223062202.3860069-1-yangyujie@loongson.cn> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxzM4iPNhl640_AA--.10922S2 X-CM-SenderInfo: 51dqw5pxmlvqxorr0wxvrqhubq/1tbiAQAQAGXXBeQI3AAOsY X-Coremail-Antispam: 1Uk129KBj9fXoWfWr43ArWUKr4DWFWfCFWDJrc_yoW8KF1UKo W3AFZ5Xr18Gr1F93y8twnagrWjqFn8ArW7Aay7uw1fWFn7Zr15Jry7Kw1Yva43ArsxXrW5 CasFg3ZrZFyxJFn3l-sFpf9Il3svdjkaLaAFLSUrUUUUUb8apTn2vfkv8UJUUUU8wcxFpf 9Il3svdxBIdaVrn0xqx4xG64xvF2IEw4CE5I8CrVC2j2Jv73VFW2AGmfu7bjvjm3AaLaJ3 UjIYCTnIWjp_UUUY17kC6x804xWl14x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI 8IcIk0rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xG Y2AK021l84ACjcxK6xIIjxv20xvE14v26r1j6r1xM28EF7xvwVC0I7IYx2IY6xkF7I0E14 v26r1j6r4UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7CjxVAF wI0_Gr1j6F4UJwAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07AIYIkI8VC2zVCFFI 0UMc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWUJVWUGwAv7VC2z280 aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JMxAIw28Icx kI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2Iq xVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42 IY6xIIjxv20xvE14v26r1j6r1xMIIF0xvE2Ix0cI8IcVCY1x0267AKxVWUJVW8JwCI42IY 6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aV CY1x0267AKxVWUJVW8JbIYCTnIWIevJa73UjIFyTuYvjxUzsqWUUUUU 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, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_FAIL, SPF_HELO_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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}. * config/loongarch/loongarch.opt: Same. * config/loongarch/loongarch-def.h: Modify ABI condition macros for convenience. * config/loongarch/loongarch-opts.cc: Define option-handling procedures split from the original loongarch_option_override_internal. * config/loongarch/loongarch-opts.h: Same. * config/loongarch/loongarch.cc: Clean up loongarch_option_override_internal. --- 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 7eeac43ed2f..e5f27b8716f 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 0428b6e65d5..8f686ee4096 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 { @@ -5905,17 +5902,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. */ @@ -7606,118 +7592,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; @@ -7726,115 +7609,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 8b453ab3140..b30ba340083 100644 --- a/gcc/config/loongarch/loongarch.h +++ b/gcc/config/loongarch/loongarch.h @@ -713,12 +713,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)