Hi Richard,

A few comments:

+void
+aarch64_expand_stshh_builtin (tree exp, int fcode)
+{
+  machine_mode mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
+  rtx val = expand_normal (CALL_EXPR_ARG (exp, 1));
+  rtx mem_order = expand_normal (CALL_EXPR_ARG (exp, 2));
+  rtx ret = expand_normal (CALL_EXPR_ARG (exp, 3));

We'll need a check mem_order and ret are constants and within range.

+  switch (fcode)
+    {
+      case AARCH64_BUILTIN_STSHH_SF:
+       {
+         rtx ival = gen_reg_rtx (SImode);
+         emit_move_insn (ival, gen_lowpart (SImode, val));

We prefer to use force_lowpart_subreg for these cases, see eg. isfinite 
expander.

+         val = ival;
+         mode = SImode;
+         break;
+       }
+      case AARCH64_BUILTIN_STSHH_DF:
+       {
+         rtx ival = gen_reg_rtx (DImode);
+         emit_move_insn (ival, gen_lowpart (DImode, val));

Same here.

+         val = ival;
+         mode = DImode;
+         break;
+       }
+      default:
+       {
+         if (!register_operand (val, mode))
+         val = force_reg (mode, val);
+         break;
+       }
+    }

--- a/gcc/config/aarch64/aarch64-option-extensions.def
+++ b/gcc/config/aarch64/aarch64-option-extensions.def
@@ -289,6 +289,8 @@ AARCH64_OPT_EXTENSION ("sme-lutv2", SME_LUTv2, (SME2), (), 
(), "sme-lutv2")
 
 AARCH64_OPT_EXTENSION("cpa", CPA, (), (), (), "")
 
+AARCH64_OPT_EXTENSION ("pcdphint", PCDPHINT, (), (), (), "")


I think this part was already separately committed on latest trunk.


+++ b/gcc/config/aarch64/arm_acle.h

+#define __atomic_store_with_stshh(addr, value, memory_order, ret)      \
+({                                                                     \
+  __auto_type ptr = (addr);                                            \
+  typedef __typeof__ (*ptr) ptr_type;                                  \
+  _Generic ((*addr),                                                   \
+    char:                __builtin_aarch64_stshh_qi,    \
+    unsigned char:       __builtin_aarch64_stshh_qi,    \
+    signed char:         __builtin_aarch64_stshh_qi,    \
+    unsigned short:       __builtin_aarch64_stshh_hi,  \
+    short:               __builtin_aarch64_stshh_hi,    \
+    unsigned int:        __builtin_aarch64_stshh_si,    \
+    int:                 __builtin_aarch64_stshh_si,    \
+    unsigned long:       __builtin_aarch64_stshh_di,    \
+    long:                __builtin_aarch64_stshh_di,    \
+    unsigned long long:   __builtin_aarch64_stshh_di,  \
+    long long:           __builtin_aarch64_stshh_di,    \
+    float:               __builtin_aarch64_stshh_sf,    \
+    double:              __builtin_aarch64_stshh_df,    \
+    default:             __builtin_aarch64_stshh_di     \
+  )((addr), (ptr_type)(value), (memory_order), (ret)); \
+})

This works fine now - I still think it is not ideal, but we can always improve 
it
in the future.


diff --git a/gcc/config/aarch64/atomics.md b/gcc/config/aarch64/atomics.md
index d4b4afb5815..db9b4fda6fe 100644
--- a/gcc/config/aarch64/atomics.md
+++ b/gcc/config/aarch64/atomics.md
@@ -751,6 +751,29 @@
   [(set_attr "arch" "*,rcpc8_4")]
 )
 
+(define_insn "@aarch64_atomic_store_stshh<mode>"
+  [(set (match_operand:ALLI 0 "aarch64_sync_memory_operand" "=Q,Ust")

Surely aarch64_rcpc_memory_operand like atomic_store above?

+    (unspec_volatile:ALLI
+       [(match_operand:ALLI 1 "register_operand" "r,r")

Surely rZ,rZ? And it would be nice to have zero stored in one of the test cases.

+       (match_operand:SI 2 "const_int_operand")                        ;; model
+       (match_operand:SI 3 "const_int_operand")]               ;; ret_policy
+      UNSPECV_STSHH))]
+  ""
+  {
+    if (INTVAL (operands[3]) == 0)
+      output_asm_insn ("stshh keep", operands);

Use '\t' rather than a space before 'keep' / 'strm'.

+    else
+      output_asm_insn ("stshh strm", operands);
+    enum memmodel model = memmodel_from_int (INTVAL (operands[2]));
+    if (is_mm_relaxed (model))

This will also need || is_mm_consume (model) || is_mm_acquire (model) unless
you explicitly block those in the intrinsic expansion.

+      return "str<atomic_sfx>\t%<w>1, %0";
+    else if (which_alternative == 0)
+      return "stlr<atomic_sfx>\t%<w>1, %0";
+    else
+      return "stlur<atomic_sfx>\t%<w>1, %0";
+  }

Missing [(set_attr "arch" "*,rcpc8_4")]




diff --git a/gcc/testsuite/gcc.target/aarch64/atomic_store_with_stshh.c.c 
b/gcc/testsuite/gcc.target/aarch64/atomic_store_with_stshh.c.c


Can we just use atomic_store_with_stshh.c rather than .c.c?

Can we have a few cases with a non-zero pointer offset and a store of zero to 
verify those cases
work correctly?

\ No newline at end of file

Please fix.

Cheers,
Wilco

Reply via email to