Supported options:
-mfrecipe -mdiv32 -mlam-bh -mlamcas -mscq -mld-seq-sa.
gcc/ChangeLog:
* config/loongarch/loongarch-target-attr.cc
(struct loongarch_attribute_info): Add options, and generate
the structure through macro definition.
(LARCH_ATTR_MASK): New macro.
(LARCH_ATTR_ENUM): Likewise.
(LARCH_ATTR_BOOL): Likewise.
(loongarch_handle_option): Support for new options.
(loongarch_process_one_target_attr): Likewise.
* doc/extend.texi: Add new attribute description information.
gcc/testsuite/ChangeLog:
* gcc.target/loongarch/pragma-la64V1_1.c: New test.
---
gcc/config/loongarch/loongarch-target-attr.cc | 86 ++++++++++++++----
gcc/doc/extend.texi | 44 ++++++++++
.../gcc.target/loongarch/pragma-la64V1_1.c | 87 +++++++++++++++++++
3 files changed, 202 insertions(+), 15 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/loongarch/pragma-la64V1_1.c
diff --git a/gcc/config/loongarch/loongarch-target-attr.cc
b/gcc/config/loongarch/loongarch-target-attr.cc
index 922aa0483b5..f7a93782372 100644
--- a/gcc/config/loongarch/loongarch-target-attr.cc
+++ b/gcc/config/loongarch/loongarch-target-attr.cc
@@ -52,28 +52,64 @@ enum loongarch_attr_opt_type
struct loongarch_attribute_info
{
const char *name;
+ unsigned int opt_mask;
enum loongarch_attr_opt_type attr_type;
- bool allow_neg;
enum opt_code opt_num;
+ bool allow_neg;
};
+
+/* Construct a loongarch_attributes from the given arguments.
+
+ OPTS is the name of the compilation option after the "-m" string.
+
+ OPTNUM is the opt_code corresponding to the compilation option.
+
+ OPTMASK is the mask corresponding to the mutation option. If the
+ compilation option does not have a corresponding mask, pass 0.
+ */
+#define LARCH_ATTR_MASK(OPTS, OPTNUM, OPTMASK) \
+ { \
+ OPTS, OPTMASK, loongarch_attr_mask, OPTNUM, true \
+ }
+
+#define LARCH_ATTR_ENUM(OPTS, OPTNUM, OPTMASK) \
+ { \
+ OPTS, OPTMASK, loongarch_attr_enum, OPTNUM, false \
+ }
+
+#define LARCH_ATTR_BOOL(OPTS, OPTNUM, OPTMASK) \
+ { \
+ OPTS, OPTMASK, loongarch_attr_bool, OPTNUM, true \
+ }
+
/* The target attributes that we support. */
static const struct loongarch_attribute_info loongarch_attributes[] =
{
- { "strict-align", loongarch_attr_mask, true, OPT_mstrict_align },
- { "cmodel", loongarch_attr_enum, false, OPT_mcmodel_ },
- { "arch", loongarch_attr_enum, false, OPT_march_ },
- { "tune", loongarch_attr_enum, false, OPT_mtune_ },
- { "lsx", loongarch_attr_bool, true, OPT_mlsx },
- { "lasx", loongarch_attr_bool, true, OPT_mlasx },
- { NULL, loongarch_attr_bool, false, OPT____ }
+ LARCH_ATTR_MASK ("strict-align", OPT_mstrict_align, MASK_STRICT_ALIGN),
+ LARCH_ATTR_ENUM ("cmodel", OPT_mcmodel_, 0),
+ LARCH_ATTR_ENUM ("arch", OPT_march_, 0),
+ LARCH_ATTR_ENUM ("tune", OPT_mtune_, 0),
+ LARCH_ATTR_BOOL ("lsx", OPT_mlsx, 0),
+ LARCH_ATTR_BOOL ("lasx", OPT_mlasx, 0),
+ LARCH_ATTR_BOOL ("frecipe", OPT_mfrecipe, OPTION_MASK_ISA_FRECIPE),
+ LARCH_ATTR_BOOL ("div32", OPT_mdiv32, OPTION_MASK_ISA_DIV32),
+ LARCH_ATTR_BOOL ("lam-bh", OPT_mlam_bh, OPTION_MASK_ISA_LAM_BH),
+ LARCH_ATTR_BOOL ("lamcas", OPT_mlamcas, OPTION_MASK_ISA_LAMCAS),
+ LARCH_ATTR_BOOL ("scq", OPT_mscq, OPTION_MASK_ISA_SCQ),
+ LARCH_ATTR_BOOL ("ld-seq-sa", OPT_mld_seq_sa, OPTION_MASK_ISA_LD_SEQ_SA),
+ { NULL, 0, loongarch_attr_bool, OPT____, false }
};
+#undef LARCH_ATTR_MASK
+#undef LARCH_ATTR_ENUM
+#undef LARCH_ATTR_BOOL
-bool
+static bool
loongarch_handle_option (struct gcc_options *opts,
struct gcc_options *opts_set ATTRIBUTE_UNUSED,
const struct cl_decoded_option *decoded,
- location_t loc ATTRIBUTE_UNUSED)
+ location_t loc ATTRIBUTE_UNUSED,
+ unsigned int opt_mask ATTRIBUTE_UNUSED)
{
size_t code = decoded->opt_index;
int val = decoded->value;
@@ -82,9 +118,9 @@ loongarch_handle_option (struct gcc_options *opts,
{
case OPT_mstrict_align:
if (val)
- opts->x_target_flags |= MASK_STRICT_ALIGN;
+ opts->x_target_flags |= opt_mask;
else
- opts->x_target_flags &= ~MASK_STRICT_ALIGN;
+ opts->x_target_flags &= ~opt_mask;
return true;
case OPT_mcmodel_:
@@ -124,6 +160,23 @@ loongarch_handle_option (struct gcc_options *opts,
? ISA_EXT_SIMD_LSX : ISA_EXT_NONE);
return true;
+ case OPT_mfrecipe:
+ case OPT_mdiv32:
+ case OPT_mlam_bh:
+ case OPT_mlamcas:
+ case OPT_mscq:
+ case OPT_mld_seq_sa:
+ if (val)
+ {
+ opts->x_la_isa_evolution |= opt_mask;
+ opts_set->x_la_isa_evolution |= opt_mask;
+ }
+ else
+ {
+ opts->x_la_isa_evolution &= ~opt_mask;
+ opts_set->x_la_isa_evolution &= ~opt_mask;
+ }
+ return true;
default:
return true;
}
@@ -196,7 +249,8 @@ loongarch_process_one_target_attr (char *arg_str,
location_t loc)
decoded.value = !invert;
loongarch_handle_option (&global_options, &global_options_set,
- &decoded, input_location);
+ &decoded, input_location,
+ p_attr->opt_mask);
break;
}
@@ -222,7 +276,8 @@ loongarch_process_one_target_attr (char *arg_str,
location_t loc)
if (valid)
loongarch_handle_option (&global_options,
&global_options_set,
- &decoded, input_location);
+ &decoded, input_location,
+ p_attr->opt_mask);
else
error_at (loc, "pragma or attribute %<target(\"%s=%s\")%> is "
"not valid", str_to_check, arg);
@@ -237,7 +292,8 @@ loongarch_process_one_target_attr (char *arg_str,
location_t loc)
generate_option (p_attr->opt_num, NULL, !invert,
CL_TARGET, &decoded);
loongarch_handle_option (&global_options, &global_options_set,
- &decoded, input_location);
+ &decoded, input_location,
+ p_attr->opt_mask);
break;
}
default:
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 94b76b75565..7aa0cbdfaf9 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -4836,6 +4836,50 @@ But the following method cannot perform 128-bit
vectorization.
$ gcc test.c -o test.s -O2 -mlasx -mno-lasx
@end smallexample
+@cindex @code{recipe} function attribute, LoongArch
+@item recipe
+@itemx no-recipe
+@code{recipe} indicates that frecipe.@{s/d@} and frsqrt.@{s/d@}instruction
generation
+is allowed (not allowed) when compiling the function. The behavior is same as
for
+the command-line option
+@option{-mrecipe} and @option{-mno-recipe}.
+
+@cindex @code{div32} function attribute, LoongArch
+@item div32
+@itemx no-div32
+@code{div32} determines whether div.w[u] and mod.w[u] instructions on 64-bit
machines
+are evaluated based only on the lower 32 bits of the input registers.
+@option{-mdiv32} and @option{-mno-div32}.
+
+@cindex @code{lam-bh} function attribute, LoongArch
+@item lam-bh
+@itemx no-lam-bh
+@code{lam-bh} indicates that am@{swap/add@}[_db].@{b/h@} instruction generation
+is allowed (not allowed) when compiling the function. The behavior is same as
for
+the command-line option
+@option{-mlam-bh} and @option{-mno-lam-bh}.
+
+@cindex @code{lamcas} function attribute, LoongArch
+@item lamcas
+@itemx no-lamcas
+@code{lamcas} indicates that amcas[_db].@{b/h/w/d@} instruction generation
+is allowed (not allowed) when compiling the function. The behavior is same as
for
+the command-line option
+@option{-mlamcas} and @option{-mno-lamcas}.
+
+@cindex @code{scq} function attribute, LoongArch
+@item scq
+@itemx no-scq
+@code{scq} indicates that sc.q instruction generation is allowed (not allowed)
when
+compiling the function. The behavior is same as for the command-line option
+@option{-mscq} and @option{-mno-scq}.
+
+@cindex @code{ld-seq-sa} function attribute, LoongArch
+@item ld-seq-sa
+@itemx no-ld-seq-sa
+@code{ld-seq-sa} indicates that whether need load-load barries (dbar 0x700)
+@option{-mld-seq-sa} and @option{-mno-ld-seq-sa}.
+
@end table
@node M32C Function Attributes
diff --git a/gcc/testsuite/gcc.target/loongarch/pragma-la64V1_1.c
b/gcc/testsuite/gcc.target/loongarch/pragma-la64V1_1.c
new file mode 100644
index 00000000000..6165d95493b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/pragma-la64V1_1.c
@@ -0,0 +1,87 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=loongarch64 -std=gnu11" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+
+/*
+** frecipe:
+** frecipe.s \$f0,\$f0
+** jr \$r1
+*/
+#pragma GCC push_options
+#pragma GCC target ("frecipe")
+float
+frecipe (float src)
+{
+#ifndef __loongarch_frecipe
+#error "Not define __loongarch_frecipe"
+#endif
+ return __builtin_loongarch_frecipe_s (src);
+}
+#pragma GCC pop_options
+
+
+/*
+** div32:
+** div.w \$r4,\$r4,\$r5
+** jr \$r1
+*/
+#pragma GCC push_options
+#pragma GCC target ("div32")
+int
+div32 (unsigned long int a, unsigned long int b)
+{
+#ifndef __loongarch_div32
+#error "Not define __loongarch_div32"
+#endif
+ return (int)a / (int)b;
+}
+#pragma GCC pop_options
+
+#pragma GCC push_options
+#pragma GCC target ("lam-bh")
+short
+lam_bh (short *ptr, short val)
+{
+#ifndef __loongarch_lam_bh
+#error "Not define __loongarch_lam_bh"
+#endif
+ return __atomic_fetch_add (ptr, val, __ATOMIC_RELAXED);
+}
+#pragma GCC pop_options
+/* { dg-final { scan-assembler "lam_bh:.*amadd.h.*lam_bh" } } */
+
+#pragma GCC push_options
+#pragma GCC target ("lamcas")
+void
+lamcas (int *ptr, int *exp, int des)
+{
+#ifndef __loongarch_lamcas
+#error "Not define __loongarch_lamcas"
+#endif
+ __atomic_compare_exchange_n (ptr, exp, des, 0, __ATOMIC_ACQ_REL,
__ATOMIC_RELAXED);
+}
+#pragma GCC pop_options
+/* { dg-final { scan-assembler "lamcas:.*amcas_db.w.*lamcas" } } */
+
+#pragma GCC push_options
+#pragma GCC target ("scq")
+void
+scq (int *ptr, int *exp, int des)
+{
+#ifndef __loongarch_scq
+#error "Not define __loongarch_scq"
+#endif
+}
+#pragma GCC pop_options
+
+#pragma GCC push_options
+#pragma GCC target ("ld-seq-sa")
+void
+ld_seq_sa (int *ptr, int *exp, int des)
+{
+#ifndef __loongarch_ld_seq_sa
+#error "Not define __loongarch_ld_seq_sa"
+#endif
+}
+#pragma GCC pop_options
--
2.34.1