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:
parent
7f424c3167
commit
d28ea8e5a7
7 changed files with 341 additions and 235 deletions
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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 \
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue