LoongArch: Split loongarch_option_override_internal into smaller procedures

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=<string> 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.
This commit is contained in:
Yang Yujie 2024-03-30 16:43:14 +08:00 committed by Lulu Cheng
parent 7f424c3167
commit d28ea8e5a7
7 changed files with 341 additions and 235 deletions

View file

@ -197,14 +197,14 @@ mexplicit-relocs
Target Alias(mexplicit-relocs=, always, none) Target Alias(mexplicit-relocs=, always, none)
Use %reloc() assembly operators (for backward compatibility). 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= mrecip=
Target RejectNegative Joined Var(la_recip_name) Save Target RejectNegative Joined Var(la_recip_name) Save
Control generation of reciprocal estimates. 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. ; The code model option names for -mcmodel.
Enum Enum
Name(cmodel) Type(int) Name(cmodel) Type(int)

View file

@ -90,11 +90,16 @@ extern loongarch_def_array<const char *, N_ABI_BASE_TYPES>
#define TO_LP64_ABI_BASE(C) (C) #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) (abi_base == ABI_BASE_LP64D)
#define ABI_FPU_32(abi_base) \ #define ABI_FPU32_P(abi_base) \
(abi_base == ABI_BASE_LP64F) (abi_base == ABI_BASE_LP64F)
#define ABI_FPU_NONE(abi_base) \ #define ABI_NOFPU_P(abi_base) \
(abi_base == ABI_BASE_LP64S) (abi_base == ABI_BASE_LP64S)

View file

@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h" #include "coretypes.h"
#include "tm.h" #include "tm.h"
#include "obstack.h" #include "obstack.h"
#include "opts.h"
#include "diagnostic-core.h" #include "diagnostic-core.h"
#include "loongarch-cpu.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-str.h"
#include "loongarch-def.h" #include "loongarch-def.h"
/* Target configuration */
struct loongarch_target la_target; struct loongarch_target la_target;
/* RTL cost information */
const struct loongarch_rtx_cost_data *loongarch_cost;
/* ABI-related configuration. */ /* ABI-related configuration. */
#define ABI_COUNT (sizeof(abi_priority_list)/sizeof(struct loongarch_abi)) #define ABI_COUNT (sizeof(abi_priority_list)/sizeof(struct loongarch_abi))
static const struct loongarch_abi static const struct loongarch_abi
@ -795,3 +800,251 @@ loongarch_update_gcc_opt_status (struct loongarch_target *target,
/* ISA evolution features */ /* ISA evolution features */
opts->x_la_isa_evolution = target->isa.evolution; opts->x_la_isa_evolution = target->isa.evolution;
} }
/* -mrecip=<str> 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=<recip_string>. */
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);
}

View file

@ -30,6 +30,10 @@ along with GCC; see the file COPYING3. If not see
/* Target configuration */ /* Target configuration */
extern struct loongarch_target la_target; 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. */ /* Initialize loongarch_target from separate option variables. */
void void
loongarch_init_target (struct loongarch_target *target, loongarch_init_target (struct loongarch_target *target,
@ -46,11 +50,30 @@ loongarch_config_target (struct loongarch_target *target,
struct loongarch_flags *flags, struct loongarch_flags *flags,
int follow_multilib_list_p); 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" */ /* option status feedback for "gcc --help=target -Q" */
void void
loongarch_update_gcc_opt_status (struct loongarch_target *target, loongarch_update_gcc_opt_status (struct loongarch_target *target,
struct gcc_options *opts, struct gcc_options *opts,
struct gcc_options *opts_set); struct gcc_options *opts_set);
/* Parser for -mrecip=<recip_string>. */
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 #endif
/* Flag status */ /* Flag status */
@ -80,9 +103,7 @@ struct loongarch_flags {
#define TARGET_DOUBLE_FLOAT_ABI (la_target.abi.base == ABI_BASE_LP64D) #define TARGET_DOUBLE_FLOAT_ABI (la_target.abi.base == ABI_BASE_LP64D)
#define TARGET_64BIT (la_target.isa.base == ISA_BASE_LA64) #define TARGET_64BIT (la_target.isa.base == ISA_BASE_LA64)
#define TARGET_ABI_LP64 (la_target.abi.base == ABI_BASE_LP64D \ #define TARGET_ABI_LP64 ABI_LP64_P(la_target.abi.base)
|| la_target.abi.base == ABI_BASE_LP64F \
|| la_target.abi.base == ABI_BASE_LP64S)
#define ISA_HAS_LSX \ #define ISA_HAS_LSX \
(la_target.isa.simd == ISA_EXT_SIMD_LSX \ (la_target.isa.simd == ISA_EXT_SIMD_LSX \

View file

@ -208,9 +208,6 @@ const enum reg_class loongarch_regno_to_class[FIRST_PSEUDO_REGISTER] = {
FRAME_REGS, FRAME_REGS FRAME_REGS, FRAME_REGS
}; };
/* Which cost information to use. */
static const struct loongarch_rtx_cost_data *loongarch_cost;
/* Information about a single argument. */ /* Information about a single argument. */
struct loongarch_arg_info 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 /* PRINT_OPERAND prefix LETTER refers to the integer branch instruction
associated with condition CODE. Print the condition part of the associated with condition CODE. Print the condition part of the
opcode to FILE. */ opcode to FILE. */
@ -7625,118 +7611,15 @@ loongarch_init_machine_status (void)
} }
static void static void
loongarch_cpu_option_override (struct loongarch_target *target, loongarch_global_init (void)
struct gcc_options *opts,
struct gcc_options *opts_set)
{ {
/* alignments */ /* Initialize loongarch_print_operand_punct. */
if (opts->x_flag_align_functions && !opts->x_str_align_functions) for (const char *p = ".$"; *p; p++)
opts->x_str_align_functions loongarch_print_operand_punct[(unsigned char) *p] = true;
= 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)
{
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 ();
/* Set up array to map GCC register number to debug register number. /* Set up array to map GCC register number to debug register number.
Ignore the special purpose register numbers. */ Ignore the special purpose register numbers. */
for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{ {
if (GP_REG_P (i) || FP_REG_P (i)) if (GP_REG_P (i) || FP_REG_P (i))
loongarch_dwarf_regno[i] = 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. */ /* Set up loongarch_hard_regno_mode_ok. */
for (mode = 0; mode < MAX_MACHINE_MODE; mode++) for (int mode = 0; mode < MAX_MACHINE_MODE; mode++)
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
loongarch_hard_regno_mode_ok_p[mode][regno] loongarch_hard_regno_mode_ok_p[mode][regno]
= loongarch_hard_regno_mode_ok_uncached (regno, (machine_mode) mode); = loongarch_hard_regno_mode_ok_uncached (regno, (machine_mode) mode);
/* Function to allocate machine-dependent function status. */ /* Function to allocate machine-dependent function status. */
init_machine_status = &loongarch_init_machine_status; init_machine_status = &loongarch_init_machine_status;
};
/* -mrecip options. */ static void
static struct loongarch_option_override_internal (struct loongarch_target *target,
{ struct gcc_options *opts,
const char *string; /* option name. */ struct gcc_options *opts_set)
unsigned int mask; /* mask bits to set. */ {
} /* Handle options not covered by struct loongarch_target. */
const recip_options[] = { loongarch_init_misc_options (opts, opts_set);
{ "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) /* Resolve the target struct. */
{ loongarch_init_target (target,
char *p = ASTRDUP (la_recip_name); opts->x_la_opt_cpu_arch,
char *q; opts->x_la_opt_cpu_tune,
unsigned int mask, i; opts->x_la_opt_fpu,
bool invert; 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);
while ((q = strtok (p, ",")) != NULL) loongarch_config_target (target, NULL, 0);
{
p = NULL;
if (*q == '!')
{
invert = true;
q++;
}
else
invert = false;
if (!strcmp (q, "default")) /* Override some options according to the resolved target. */
mask = RECIP_MASK_ALL; loongarch_target_option_override (target, opts, opts_set);
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)
#undef INIT_TARGET_FLAG
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);
} }
/* Implement TARGET_OPTION_OVERRIDE. */ /* Implement TARGET_OPTION_OVERRIDE. */
static void static void
loongarch_option_override (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. */ /* Implement TARGET_OPTION_SAVE. */

View file

@ -710,12 +710,18 @@ enum reg_class
| RECIP_MASK_RSQRT | RECIP_MASK_VEC_SQRT \ | RECIP_MASK_RSQRT | RECIP_MASK_VEC_SQRT \
| RECIP_MASK_VEC_DIV | RECIP_MASK_VEC_RSQRT) | RECIP_MASK_VEC_DIV | RECIP_MASK_VEC_RSQRT)
#define TARGET_RECIP_DIV ((recip_mask & RECIP_MASK_DIV) != 0 || TARGET_uARCH_LA664) #define TARGET_RECIP_DIV \
#define TARGET_RECIP_SQRT ((recip_mask & RECIP_MASK_SQRT) != 0 || TARGET_uARCH_LA664) ((recip_mask & RECIP_MASK_DIV) != 0 && ISA_HAS_FRECIPE)
#define TARGET_RECIP_RSQRT ((recip_mask & RECIP_MASK_RSQRT) != 0 || TARGET_uARCH_LA664) #define TARGET_RECIP_SQRT \
#define TARGET_RECIP_VEC_DIV ((recip_mask & RECIP_MASK_VEC_DIV) != 0 || TARGET_uARCH_LA664) ((recip_mask & RECIP_MASK_SQRT) != 0 && ISA_HAS_FRECIPE)
#define TARGET_RECIP_VEC_SQRT ((recip_mask & RECIP_MASK_VEC_SQRT) != 0 || TARGET_uARCH_LA664) #define TARGET_RECIP_RSQRT \
#define TARGET_RECIP_VEC_RSQRT ((recip_mask & RECIP_MASK_VEC_RSQRT) != 0 || TARGET_uARCH_LA664) ((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. /* 1 if N is a possible register number for function argument passing.
We have no FP argument registers when soft-float. */ We have no FP argument registers when soft-float. */

View file

@ -205,14 +205,14 @@ mexplicit-relocs
Target Alias(mexplicit-relocs=, always, none) Target Alias(mexplicit-relocs=, always, none)
Use %reloc() assembly operators (for backward compatibility). 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= mrecip=
Target RejectNegative Joined Var(la_recip_name) Save Target RejectNegative Joined Var(la_recip_name) Save
Control generation of reciprocal estimates. 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. ; The code model option names for -mcmodel.
Enum Enum
Name(cmodel) Type(int) Name(cmodel) Type(int)