diff options
author | Cupertino Miranda <cupertino.miranda@oracle.com> | 2024-07-11 15:28:09 +0100 |
---|---|---|
committer | Cupertino Miranda <cupertino.miranda@oracle.com> | 2024-07-19 13:19:53 +0100 |
commit | 8fbc386c12385378b01a744c6764b5660d4b4310 (patch) | |
tree | 133e72d10cbe2a863f09fe98aa771f471fa3ae3c | |
parent | cea6473e48b4cfbf16f7b4a804f1562f8da8f25b (diff) | |
download | gcc-8fbc386c12385378b01a744c6764b5660d4b4310.zip gcc-8fbc386c12385378b01a744c6764b5660d4b4310.tar.gz gcc-8fbc386c12385378b01a744c6764b5660d4b4310.tar.bz2 |
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.
-rw-r--r-- | gcc/config/bpf/atomic.md | 4 | ||||
-rw-r--r-- | gcc/config/bpf/bpf.cc | 20 | ||||
-rw-r--r-- | gcc/testsuite/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 65bd5f2..be4511b 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 c62af7a..2051fa5 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 0000000..eb4f979 --- /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 } } */ + |