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

Reply via email to