https://gcc.gnu.org/g:8fbc386c12385378b01a744c6764b5660d4b4310

commit r15-2153-g8fbc386c12385378b01a744c6764b5660d4b4310
Author: Cupertino Miranda <cupertino.mira...@oracle.com>
Date:   Thu Jul 11 15:28:09 2024 +0100

    bpf: create modifier for mem operand for xchg and cmpxchg
    
    Both xchg and cmpxchg instructions, in the pseudo-C dialect, do not
    expect their memory address operand to be surrounded by parentheses.
    For example, it should be output as "w0 =cmpxchg32_32(r8+8,w0,w2)"
    instead of "w0 =cmpxchg32_32((r8+8),w0,w2)".
    
    This patch implements an operand modifier 'M' which marks the
    instruction templates that do not expect the parentheses, and adds it do
    xchg and cmpxchg templates.
    
    gcc/ChangeLog:
            * config/bpf/atomic.md (atomic_compare_and_swap,
            atomic_exchange): Add operand modifier %M to the first
            operand.
            * config/bpf/bpf.cc (no_parentheses_mem_operand): Create
            variable.
            (bpf_print_operand): Set no_parentheses_mem_operand variable if
            %M operand is used.
            (bpf_print_operand_address): Conditionally output parentheses.
    
    gcc/testsuite/ChangeLog:
            * gcc.target/bpf/pseudoc-atomic-memaddr-op.c: Add test.

Diff:
---
 gcc/config/bpf/atomic.md                           |  4 +--
 gcc/config/bpf/bpf.cc                              | 20 +++++++++---
 .../gcc.target/bpf/pseudoc-atomic-memaddr-op.c     | 38 ++++++++++++++++++++++
 3 files changed, 56 insertions(+), 6 deletions(-)

diff --git a/gcc/config/bpf/atomic.md b/gcc/config/bpf/atomic.md
index 65bd5f266a15..be4511bb51bf 100644
--- a/gcc/config/bpf/atomic.md
+++ b/gcc/config/bpf/atomic.md
@@ -129,7 +129,7 @@
    (set (match_dup 1)
         (match_operand:AMO 2 "nonmemory_operand" "0"))]
   "bpf_has_v3_atomics"
-  "{axchg<msuffix>\t%1,%0|%w0 = xchg<pcaxsuffix>(%1, %w0)}")
+  "{axchg<msuffix>\t%1,%0|%w0 = xchg<pcaxsuffix>(%M1, %w0)}")
 
 ;; The eBPF atomic-compare-and-exchange instruction has the form
 ;;   acmp [%dst+offset], %src
@@ -182,4 +182,4 @@
           (match_operand:AMO 3 "register_operand")]   ;; desired
          UNSPEC_ACMP))]
   "bpf_has_v3_atomics"
-  "{acmp<msuffix>\t%1,%3|%w0 = cmpxchg<pcaxsuffix>(%1, %w0, %w3)}")
+  "{acmp<msuffix>\t%1,%3|%w0 = cmpxchg<pcaxsuffix>(%M1, %w0, %w3)}")
diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index c62af7a6efa7..2051fa5b08b1 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -830,6 +830,11 @@ bpf_print_register (FILE *file, rtx op, int code)
     }
 }
 
+/* Variable defined to implement 'M' operand modifier for the special cases
+   where the parentheses should not be printed surrounding a memory address
+   operand. */
+static bool no_parentheses_mem_operand;
+
 /* Print an instruction operand.  This function is called in the macro
    PRINT_OPERAND defined in bpf.h */
 
@@ -842,6 +847,7 @@ bpf_print_operand (FILE *file, rtx op, int code)
       bpf_print_register (file, op, code);
       break;
     case MEM:
+      no_parentheses_mem_operand = (code == 'M');
       output_address (GET_MODE (op), XEXP (op, 0));
       break;
     case CONST_DOUBLE:
@@ -886,6 +892,9 @@ bpf_print_operand (FILE *file, rtx op, int code)
     }
 }
 
+#define PAREN_OPEN  (asm_dialect == ASM_NORMAL ? "[" : 
no_parentheses_mem_operand ? "" : "(")
+#define PAREN_CLOSE (asm_dialect == ASM_NORMAL ? "]" : 
no_parentheses_mem_operand ? "" : ")")
+
 /* Print an operand which is an address.  This function should handle
    any legit address, as accepted by bpf_legitimate_address_p, and
    also addresses that are valid in CALL instructions.
@@ -899,9 +908,9 @@ bpf_print_operand_address (FILE *file, rtx addr)
   switch (GET_CODE (addr))
     {
     case REG:
-      fprintf (file, asm_dialect == ASM_NORMAL ? "[" : "(");
+      fprintf (file, "%s", PAREN_OPEN);
       bpf_print_register (file, addr, 0);
-      fprintf (file, asm_dialect == ASM_NORMAL ? "+0]" : "+0)");
+      fprintf (file, "+0%s", PAREN_CLOSE);
       break;
     case PLUS:
       {
@@ -918,14 +927,14 @@ bpf_print_operand_address (FILE *file, rtx addr)
                || (GET_CODE (op1) == UNSPEC
                    && XINT (op1, 1) == UNSPEC_CORE_RELOC)))
          {
-            fprintf (file, asm_dialect == ASM_NORMAL ? "[" : "(");
+           fprintf (file, "%s", PAREN_OPEN);
            bpf_print_register (file, op0, 0);
            fprintf (file, "+");
            if (GET_CODE (op1) == UNSPEC)
              output_addr_const (file, XVECEXP (op1, 0, 0));
            else
              output_addr_const (file, op1);
-            fprintf (file, asm_dialect == ASM_NORMAL ? "]" : ")");
+           fprintf (file, "%s", PAREN_CLOSE);
          }
        else
          fatal_insn ("invalid address in operand", addr);
@@ -943,6 +952,9 @@ bpf_print_operand_address (FILE *file, rtx addr)
     }
 }
 
+#undef PAREN_OPEN
+#undef PAREN_CLOSE
+
 /* Add a BPF builtin function with NAME, CODE and TYPE.  Return
    the function decl or NULL_TREE if the builtin was not added.  */
 
diff --git a/gcc/testsuite/gcc.target/bpf/pseudoc-atomic-memaddr-op.c 
b/gcc/testsuite/gcc.target/bpf/pseudoc-atomic-memaddr-op.c
new file mode 100644
index 000000000000..eb4f9794c936
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/pseudoc-atomic-memaddr-op.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-mv3-atomics -O2 -masm=pseudoc" } */
+
+int
+foo (int *p, int *expected, int desired)
+{
+  return __atomic_compare_exchange (p, expected, &desired, 0,
+                                   __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
+}
+
+int
+foo64 (long *p, long *expected, long desired)
+{
+  return __atomic_compare_exchange (p, expected, &desired, 0,
+                                   __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
+}
+
+int
+bar (int *p, int *new)
+{
+  int old;
+  __atomic_exchange (p, new, &old, __ATOMIC_RELAXED);
+  return old;
+}
+
+int
+bar64 (long *p, long *new)
+{
+  long old;
+  __atomic_exchange (p, new, &old, __ATOMIC_SEQ_CST);
+  return old;
+}
+
+/* { dg-final { scan-assembler "r. = cmpxchg_64\\(r.\\+0, r., r.\\)" } } */
+/* { dg-final { scan-assembler "w. = cmpxchg32_32\\(r.\\+0, w., w.\\)" } } */
+/* { dg-final { scan-assembler-times "w. = xchg32_32\\(r.\\+0, w.\\)" 1 } } */
+/* { dg-final { scan-assembler-times "r. = xchg_64\\(r.\\+0, r.\\)" 1 } } */
+

Reply via email to