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;
+